Загрузка файла

Создание поля

В модели надо добавить параметр, который будет отвечать за загрузку файла.

# model/Post.php

class FeedbackForm extends Model {

    // создание поля для загрузки файла
    public $imageFile;

}

Вывести данное поле можно через метод $form->field()->fileInput().

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
// …

$form = ActiveForm::begin();

    // Вывести поле для выборки файла
    echo $form->field($model, 'imageFile')->fileInput();

    echo Html::submitButton('Отправить');
ActiveForm::end();

Метод fileInput() автоматически подставляет параметр multipart/form-data к форме (данный параметр позволяет загружать файлы). При необходимости можно указать данный параметр вручную.

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

Загрузка файла

Загрузка файла происходит через метод saveAs().

use yii\web\UploadedFile;
// …

$model = new FeedbackForm();
if (Yii::$app->request->isPost) {
    $model->imageFile = UploadedFile::getInstance($model, 'imageFile');

    // Загрузка файла
    if ($model->validate()) {
        $model->imageFile->saveAs('uploads/'.$model->imageFile->name);
    );
}

В коде выше файл будет загружен в папку web/uploads/.

Переменная $model->imageFile содержит данные о загружаемом файле.

$model->imageFile = UploadedFile::getInstance($model, 'imageFile');

$model->imageFile->name;      // name-file.jpg (имя файла)
$model->imageFile->baseName;  // name-file (имя файла без расширения)
$model->imageFile->extension; // jpg (расширение файла)
$model->imageFile->type;      // image/jpeg (MIME файла)
$model->imageFile->size;      // 1559 (размер файла в килобайтах)

Валидация

В настройках модели можно проверять файлы, которые доступны для загрузки.

public function rules()
{
    return array(
        ['imageFile', 'file', 'extensions' => 'jpg, png'],             // загрузка указанных картинок
        ['imageFile', 'file', 'mimeTypes' => 'image/*'],               // загрузка любых картинок
        ['imageFile', 'file', 'mimeTypes' => 'image/jpeg, image/png'], // загрузка указанных картинок через MIME
        ['imageFile', 'file', 'minSize' => 5000],                      // минимальный размер (в байтах)
        ['imageFile', 'file', 'maxSize' => 20000],                     // максимальный размер (в байтах)
    );
}

Валидация extensions также проверяет MIME-файлов (т.е. идёт проверка, что файл с расширением «jpg» на самом деле является файлом «jpg»). Если проверка через MIME не работает, то надо убедиться, что параметр checkExtensionByMimeType указан как «true».

public function rules()
{
    return array(
        // при валидации «extensions» также проверять на MIME (включено по умолчанию)
        ['imageFile', 'file', 'checkExtensionByMimeType' => true]
    );
}

Yii автоматически применяет к файлам валидацю maxSize, беря максимальный допустимый размер из параметра upload_max_filesize, который указан в настройках PHP.

Также для метода $form->field()->fileInput() можно указать, что при открытии окна выборки файлов, показывать только картинки.

// показывать все картинки
$form->field($model, 'imageFile')->fileInput(['accept' => 'image/*']);

// показывать только файлы jpg и png
$form->field($model, 'imageFile')->fileInput(['accept' => 'image/png,image/jpeg']); 

Загрузка нескольких файлов

Для загрузки нескольких файлов для метода $form->field()->fileInput() надо добавить параметр «multiple», и в имени поля добавить квадратные скобки.

// Загрузка несколько файлов
$form->field($model, 'imageFiles[]')->fileInput(['multiple' => true]);

И сделать правки в контроллере.

use yii\web\UploadedFile;
// …

$model = new FeedbackForm();
if (Yii::$app->request->isPost) {
    // "getInstances" вместо "getInstance"
    $model->imageFiles = UploadedFile::getInstances($model, 'imageFiles');

    // Загрузка файлов
    if ($model->validate()) {
        foreach ($model->imageFiles as $file) {
           $file->saveAs('uploads/'.$file->name);
        }
    );
}

При необходимости можно указать допустимое количество загружаемых файлов через валидацию maxFiles.

public function rules()
{
    // Максимальное число загружаемых файлов одновременно
    return array(
        ['imageFiles', 'file', 'maxFiles' => 5]
    );
}

Также надо убедиться, что максимальное число файлов не превышает параметр max_file_uploads, который указан в настройках PHP.