Skip to content

Latest commit

 

History

History
129 lines (117 loc) · 6.64 KB

172-174 Загрузка файлов.md

File metadata and controls

129 lines (117 loc) · 6.64 KB

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

Обработка загрузки файлов является довольно распространенной задачей для веб-приложения. Yii имеет некоторые полезные классы, встроенные для этого. Давайте создадим простую форму, которая позволит загружать ZIP архивы и хранить их в /uploads.

Подготовка

1 Создайте новое приложение с помощью composer, как описано в официальном руководстве по http://www.yiiframework.com/doc-2.0/guide-start-installation.html. по русски http://yiiframework.domain-na.me/doc/guide/2.0/ru/start-installation.

2 Создайте каталог @app/web/uploads

Как это сделать...

1 Мы начнем с модели, поэтому создайте модель @app/models/Upload.php следующим образом:

<?php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
    /**
    * @var UploadedFile
    */
    public $file;
    public function rules()
    {
        return [
            ['file', 'file', 'skipOnEmpty' => false, 'extensions' => 'zip'],
        ];
    }
    public function upload()
    {
        if ($this->validate()) {
            $this->file->saveAs('uploads/' . $this->file->baseName . '.'	. $this->file->extension);
            return true;
        } else {
            return false;
        }
    }
}

2 Теперь перейдем к контроллеру, поэтому создадим @app/controllers/UploadController.php как:

<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class UploadController extends Controller
{
    public function actionUpload()
    {
        $model = new UploadForm();
        if (Yii::$app->request->isPost) {
            $model->file = UploadedFile::getInstance($model, 'file');
            if ($model->upload()) {
                return $this->renderContent("File {$model->file->name} is uploaded successfully");
            }
        }
        return $this->render('index', ['model' => $model]);
    }
}

3 Наконец, Вы можете просмотреть @app/views/upload/index.php следующим образом:

<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'file')->fileInput() ?>
<?= Html::submitButton('Upload', ['class' => 'btn-success'])?>
<?php ActiveForm::end() ?>

4 Вот и все. Теперь запустите контроллер загрузки и попробуйте загрузить как ZIP-архивы, так и другие файлы, как показано на следующем снимке экрана:

Как это работает...

Модель, которую мы используем, довольно проста. Мы определяем только одно поле с именем $file и правило проверки, которое использует файловый валидатор FileValidator, который читает только ZIP-файлы. Мы создаем экземпляр модели и заполняем его данными из $_POST, если форма отправлена:

$model->file = UploadedFile::getInstance($model, 'file');
if ($model->upload()) {
     return $this->renderContent("File {$model->file->name} is uploaded successfully");
}

Затем мы используем UploadedFile:: getInstance, что дает нам доступ к использованию экземпляра UploadedFile. Этот класс является оболочкой вокруг массива $_FILE, который PHP заполняет при загрузке файла. Мы удостоверяемся, что файл является ZIP-архивом, вызвав метод validate модели, затем мы сохраняем файл, используя UploadedFile:: saveAs. Для загрузки файла HTML-форма должна соответствовать следующим двум важным требованиям:

  • Метод должен быть установлен в POST
  • Атрибут enctype должен иметь значение multipart / form-data Важно помнить, что вы добавляете опцию enctype в форму, чтобы файл можно было правильно загрузить. Мы можем создать этот HTML с помощью помощника Html или ActiveForm с набором htmlOptions. Здесь использовался HTML:
<?= Html::beginForm('', 'post', ['enctype'=>'multipart/form-data'])?>

В конце концов, мы отобразим ошибку и поле для атрибута файла модели, а также отобразим кнопку Отправить.

Есть еще...

Для загрузки нескольких файлов Yii2 реализует два специальных метода. Например, вы определили $imageFiles в вашей модели в файле представления в общем все будет то же самое с небольшой разницей:

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

Чтобы получить dсе экземпляры файлов, необходимо вызвать Cuploadedfile::getInstances() вместо UploadedFile::getInstance():

$model->imageFiles = UploadedFile::getInstances($model, 'imageFiles');

Обработка и сохранение нескольких файлов может быть сделано с помощью простого фрагмента кода:

foreach ($this->imageFiles as $file) {
    $file->saveAs('uploads/' . $file->baseName .	'.' . $file->extension);
}

Смотрите так же

Для получения дополнительной информации обратитесь к: