Обработка загрузки файлов является довольно распространенной задачей для веб-приложения. 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);
}
Для получения дополнительной информации обратитесь к:
- http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html по русски http://yiiframework.domain-na.me/doc/guide/2.0/ru/input-file-upload
- http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html#uploadjng-multiple-files по русски http://yiiframework.domain-na.me/doc/guide/2.0/ru/input-file-upload#uploading-multiple-files