Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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

Загрузка файла — частая задача: обложка статьи, аватар, документ. В Yii файл принимают так же, как остальные данные формы: через модель с правилом проверки. Сам файл представляет объект класса yii\web\UploadedFile.

Модель формы

Создайте вручную файл models/UploadForm.php:

// models/UploadForm.php
namespace app\models;
 
use yii\base\Model;
 
class UploadForm extends Model
{
    public $imageFile;
 
    public function rules(): array
    {
        return [
            ['imageFile', 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
        ];
    }
}

Правило file проверяет, что файл загружен и имеет разрешённое расширение. skipOnEmpty => false делает файл обязательным.

Папка для файлов

Создайте папку web/uploads. Она находится внутри корня сайта, поэтому сохранённый файл web/uploads/cover.jpg откроется по адресу /uploads/cover.jpg. У веб-сервера должно быть право записи в неё.

Действие контроллера

// controllers/PostController.php
use app\models\UploadForm;
use yii\web\UploadedFile;
 
public function actionUpload()
{
    $model = new UploadForm();
 
    if (Yii::$app->request->isPost) {
        $model->imageFile = UploadedFile::getInstance($model, 'imageFile');
 
        if ($model->validate()) {
            $name = uniqid() . '.' . $model->imageFile->extension;
            $model->imageFile->saveAs(Yii::getAlias('@webroot/uploads/') . $name);
 
            Yii::$app->session->setFlash('success', "Файл сохранён: $name");
 
            return $this->refresh();
        }
    }
 
    return $this->render('upload', ['model' => $model]);
}

UploadedFile::getInstance() достаёт файл из запроса. Метод load() для файлов не подходит. saveAs() переносит файл из временной папки в постоянную. Псевдоним @webroot означает папку web.

Шаблон формы

Создайте views/post/upload.php:

<?php
// views/post/upload.php
 
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
 
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
 
<?= $form->field($model, 'imageFile')->fileInput() ?>
 
<?= Html::submitButton('Загрузить') ?>
 
<?php ActiveForm::end(); ?>

Откройте /post/upload, выберите картинку и отправьте форму: появится сообщение с именем файла, а сам файл окажется в web/uploads. Если выбрать файл .txt, под полем появится ошибка о недопустимом расширении.

Свойства файла

СвойствоЗначение
$file->nameИсходное имя файла на компьютере посетителя
$file->baseNameИмя без расширения
$file->extensionРасширение
$file->sizeРазмер в байтах
$file->typeТип, который сообщил браузер

Ограничения

['imageFile', 'file', 'extensions' => 'png, jpg', 'maxSize' => 2 * 1024 * 1024],

maxSize ограничивает размер — здесь двумя мегабайтами. Для картинок есть правило image с параметрами maxWidth и maxHeight. PHP имеет и собственный предел — настройку upload_max_filesize в php.ini.

Частая ошибка

Без 'enctype' => 'multipart/form-data' браузер отправит только имя файла, а не его содержимое. UploadedFile::getInstance() вернёт null, и проверка сообщит, что файл не выбран. И не сохраняйте файл под исходным именем $file->name: два посетителя с файлом photo.jpg перезапишут друг друга.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.