Szukaj…


Jak to zrobić

Przesyłanie plików

Przesyłanie plików w Yii odbywa się zwykle za pomocą [[yii \ web \ UploadedFile]], który zawiera każdy przesłany plik jako obiekt UploadedFile . W połączeniu z [[yii \ widgets \ ActiveForm]] i modelami możesz łatwo wdrożyć bezpieczny mechanizm przesyłania plików.

Tworzenie modeli

Podobnie jak praca z wprowadzaniem zwykłego tekstu, aby przesłać pojedynczy plik, należy utworzyć klasę modelu i użyć atrybutu modelu, aby zachować przesłaną instancję pliku. Należy również zadeklarować regułę sprawdzania poprawności, aby sprawdzić poprawność przesłanego pliku. Na przykład,

namespace app\models;

use yii\base\Model;
use yii\web\UploadedFile;

class UploadForm extends Model
{
    /**
     * @var UploadedFile
     */
    public $imageFile;

    public function rules()
    {
        return [
            [['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
        ];
    }
    
    public function upload()
    {
        if ($this->validate()) {
            $this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
            return true;
        } else {
            return false;
        }
    }
}

W powyższym kodzie atrybut imageFile służy do zachowania przesłanej instancji pliku. Jest on powiązany z regułą sprawdzania poprawności file która korzysta z [[yii \ validators \ FileValidator]], aby zapewnić przesłanie pliku o nazwie rozszerzenia png lub jpg . Metoda upload() przeprowadzi sprawdzenie poprawności i zapisze przesłany plik na serwerze.

Walidator file umożliwia sprawdzenie rozszerzeń plików, rozmiaru, typu MIME itp. Więcej informacji znajduje się w sekcji Core Validators.

Wskazówka: jeśli przesyłasz obraz, możesz zamiast tego rozważyć użycie walidatora image . Walidator image jest implementowany za pośrednictwem [[yii \ validators \ ImageValidator]], który sprawdza, czy atrybut otrzymał prawidłowy obraz, który można następnie zapisać lub przetworzyć za pomocą rozszerzenia Imagine .

Renderowanie pliku wejściowego

Następnie utwórz plik wejściowy w widoku:

<?php
use yii\widgets\ActiveForm;
?>

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>

    <?= $form->field($model, 'imageFile')->fileInput() ?>

    <button>Submit</button>

<?php ActiveForm::end() ?>

Ważne jest, aby pamiętać, że dodajesz opcję enctype do formularza, aby plik mógł zostać poprawnie przesłany. fileInput() spowoduje wyświetlenie <input type="file"> który pozwoli użytkownikom wybrać plik do przesłania.

Wskazówka: od wersji 2.0.8 [[yii \ web \ widgets \ ActiveField :: fileInput | fileInput]] dodaje opcję enctype do formularza automatycznie, gdy używane jest pole wejściowe pliku.

Okablowanie

Teraz w akcji kontrolera napisz kod, aby połączyć model i widok, aby zaimplementować przesyłanie plików:

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;

class SiteController extends Controller
{
    public function actionUpload()
    {
        $model = new UploadForm();

        if (Yii::$app->request->isPost) {
            $model->imageFile = UploadedFile::getInstance($model, 'imageFile');
            if ($model->upload()) {
                // file is uploaded successfully
                return;
            }
        }

        return $this->render('upload', ['model' => $model]);
    }
}

W powyższym kodzie, gdy formularz jest przesyłany, wywoływana jest metoda [[yii \ web \ UploadedFile :: getInstance ()]] w celu reprezentowania przesłanego pliku jako instancji UploadedFile . Następnie polegamy na sprawdzeniu poprawności modelu, aby upewnić się, że przesłany plik jest prawidłowy i zapisać plik na serwerze.

Przesyłanie wielu plików

Możesz także przesłać wiele plików jednocześnie, z pewnymi modyfikacjami kodu wymienionego w poprzednich podsekcjach.

Najpierw należy dostosować klasę modelu, dodając opcję maxFiles do reguły sprawdzania poprawności file aby ograniczyć maksymalną liczbę plików, które można przesłać. Ustawienie wartości maxFiles na 0 oznacza, że nie ma ograniczenia liczby plików, które można jednocześnie przesłać. Maksymalna liczba plików, które mogą być przesyłane jednocześnie, jest również ograniczona przez dyrektywę PHP max_file_uploads , która domyślnie max_file_uploads 20. Należy również zaktualizować metodę upload() aby zapisywać przesłane pliki jeden po drugim.

namespace app\models;

use yii\base\Model;
use yii\web\UploadedFile;

class UploadForm extends Model
{
    /**
     * @var UploadedFile[]
     */
    public $imageFiles;

    public function rules()
    {
        return [
            [['imageFiles'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg', 'maxFiles' => 4],
        ];
    }
    
    public function upload()
    {
        if ($this->validate()) { 
            foreach ($this->imageFiles as $file) {
                $file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
            }
            return true;
        } else {
            return false;
        }
    }
}

W pliku widoku należy dodać opcję multiple do fileInput() aby pole wysyłania pliku mogło odbierać wiele plików:

<?php
use yii\widgets\ActiveForm;
?>

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>

    <?= $form->field($model, 'imageFiles[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>

    <button>Submit</button>

<?php ActiveForm::end() ?>

I wreszcie w akcji kontrolera powinieneś wywołać UploadedFile::getInstances() zamiast UploadedFile::getInstance() aby przypisać tablicę instancji UploadedFile do UploadForm::imageFiles .

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;

class SiteController extends Controller
{
    public function actionUpload()
    {
        $model = new UploadForm();

        if (Yii::$app->request->isPost) {
            $model->imageFiles = UploadedFile::getInstances($model, 'imageFiles');
            if ($model->upload()) {
                // file is uploaded successfully
                return;
            }
        }

        return $this->render('upload', ['model' => $model]);
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow