Trong Yii2 việc tải file lên từ người dùng sẽ được thực hiện bởi đối tượng UploadFile của Yii. Các file upload lên sẽ được gói gọn dưới dạng đôi tượng UploadFIle kết hợp với đối tượng Form cuả Yii các đồng dev có thể triển khai tải tệp tin lên một cách an toàn.

Sử dụng với model

Upload 1 file đơn lẻ

Trong model, để tải tệp lên trước hết các đồng dev cần khai báo các rule cho tệp tin mình cần tải lên để xác thực tệp tin đúng theo yêu cầu. Ở đây tại hạ sẽ ví dụ triển khai UploadFIle trong model User như sau

<?php

namespace frontend\models;

use Yii;

/**
 * This is the model class for table "user".
 *
 * @property int $id
 * @property string $username
 * @property string $auth_key
 * @property string $password_hash
 * @property string|null $password_reset_token
 * @property string $email
 * @property int $status
 * @property int $created_at
 * @property int $updated_at
 * @property string|null $verification_token
 */
class User extends \yii\db\ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'user';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['username', 'password_hash', 'email'], 'required'],
            [['status', 'created_at', 'updated_at'], 'integer'],
            [['username', 'password_hash', 'password_reset_token', 'email', 'verification_token'], 'string', 'max' => 255],
            [['auth_key'], 'string', 'max' => 32],
            [['username'], 'unique'],
            [['email'], 'unique'],
            [['avatar'], 'file','extensions' => 'png, jpg'],
 
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'username' => 'Username',
            'auth_key' => 'Auth Key',
            'password_hash' => 'Password Hash',
            'password_reset_token' => 'Password Reset Token',
            'email' => 'Email',
            'status' => 'Status',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
            'verification_token' => 'Verification Token',
            'avatar' => 'avatar',
        ];
    }

}

Trong model User trên tại hạ đã khai báo cho cột avatar sẽ validate theo kiểu file và có phần mở rộng là png hoặc jpg, skipOnEmpty để bỏ qua không valid nếu giá trị trống, Rule File là luật được sử dụng từ yii \ validators \ FileValidator để đảm bảo tệp có tên mở rộng png hoặc jpg được tải lên.

Các  file validator cho phép kiểm tra phần mở rộng tập tin, kích thước, MIME loại, vv . Các đồng dev có thể tham khảo thêm tại đây.

Tiếp theo tại hạ sẽ sử dụng Form trong create view của user để hiển thị giao diện upload cho người dùng như sau

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model app\models\User */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="user-form">

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

    <?= $form->field($model, 'username')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'password_hash')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>

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

    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

Trong UserController tại hạ tạo 1 actionUpload như sau:

<?php

namespace frontend\controllers;

use Yii;
use frontend\models\User;
use frontend\models\search\UserSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\data\ActiveDataProvider;
use yii\web\UploadedFile;

/**
 * UserController implements the CRUD actions for User model.
 */
class UserController extends Controller
{ 

    //.........................

    public function actionCreate()
    {
        $model = new User();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {

            $model->avatar = UploadedFile::getInstance($model, 'avatar');
            $model->avatar->saveAs('uploads/' . $model->avatar->baseName . '.' . $model->avatar->extension); // lưu ảnh vào thư mục uploads
            
            $model->avatar = $model->avatar->baseName . '.' . $model->avatar->extension; // lưu vào database
            $model->save();

            return $this->redirect(['view', 'id' => $model->id]);
        }

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

}

Trước đó nếu thư mục upload chưa có thì anh em đồng dev sẽ phải tạo và phân full quyền cho nó để có thể lưu ảnh upload lên. Như trên tại hạ sẽ phải tạo 1 folder là uploads cùng cấp với các thư mục của dự án

yii2 upload

Giao diện sẽ như sau, trông hơi cổ điển =))

yii2 upload

Sau khi upload file sẽ xuất hiện trong thư mục uploads và lưu trữ cả trong cơ sở dữ liệu, để sử dụng file các đồng dev gọi đúng URL tới file đó là được 

yii2 upload

yii2 upload

Upload nhiều file 

Vậy là đã tại hạ đã giới thiệu xong phần upload 1 file đơn lẻ, nếu muốn upload nhiều file 1 lúc thì sao ? Để upload được nhiều file lên server 1 lúc, các đồng dev cần chú ý mục max_file_uploads trong file php.ini xem giới hạn của nó là bao nhiêu, các đồng dev cũng có thể chỉnh tăng lên tùy theo nhu cầu của mình.

Với getInstance trong UploadFile thì chỉ sử dụng cho upload 1 file đơn lẻ thì để upload nhiều file các đồng dev chỉ cần thêm đúng 1 chữ 's' là getInstances

Khi đó controller sẽ chuyển lại như sau 

<?php

namespace frontend\controllers;

use Yii;
use frontend\models\User;
use frontend\models\search\UserSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\data\ActiveDataProvider;
use yii\web\UploadedFile;

/**
 * UserController implements the CRUD actions for User model.
 */
class UserController extends Controller
{ 

    //.........................

    public function actionCreate()
    {
        $model = new User();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {

            $data_avatar = []; //mảng các avatar 
            $model->avatar = UploadedFile::getInstances($model, 'avatar');
            foreach ($model->avatar as $key => $file) {
                $file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
                $data_avatar[$key] = $file->baseName. '-' . $key . '.' . $file->extension;
            }
            $model->avatar = json_encode($data_avatar); // lưu vào database
            $model->save();

            return $this->redirect(['view', 'id' => $model->id]);
        }

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

}

Trong model User set thêm rule maxFiles 

<?php

namespace frontend\models;

use Yii;

/**
 * This is the model class for table "user".
 *
 * @property int $id
 * @property string $username
 * @property string $auth_key
 * @property string $password_hash
 * @property string|null $password_reset_token
 * @property string $email
 * @property int $status
 * @property int $created_at
 * @property int $updated_at
 * @property string|null $verification_token
 */
class User extends \yii\db\ActiveRecord
{

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'user';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['username','password_hash', 'email'], 'required'],
            [['status', 'created_at', 'updated_at'], 'integer'],
            [['username', 'password_hash', 'password_reset_token', 'email', 'verification_token'], 'string', 'max' => 255],
            [['auth_key'], 'string', 'max' => 32],
            [['username'], 'unique'],
            [['email'], 'unique'],
            [['avatar'], 'file','extensions' => 'png, jpg','maxFiles' => 4],
 
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'username' => 'Username',
            'auth_key' => 'Auth Key',
            'password_hash' => 'Password Hash',
            'password_reset_token' => 'Password Reset Token',
            'email' => 'Email',
            'status' => 'Status',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
            'verification_token' => 'Verification Token',
            'avatar' => 'avatar',
        ];
    }
}

Ở view Create của User

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model app\models\User */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="user-form">

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

    <?= $form->field($model, 'username')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'password_hash')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>

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

    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

Hiển thị với người dùng 

yii2 upload

Và kết quả là sẽ có thêm 3 file mới 

yii2 upload

yii2 upload

Ok, Vậy là tại hạ đã demo xong cơ bản về UploadFIle trong Yii2 . Đối với việc upload multi file này thì thường áp dụng cho việc upload các hình ảnh liên quan hay album của sản phẩm .....

Tổng kết

Upload File trong các ứng dụng web rất là phổ biến và việc sử dụng upload file do các framework nói chung hay Yii2 nói riêng là điều cần thiết trong quá trình phát triển ứng dụng. Nhưng các anh em đồng dev cần lưu ý việc để người dùng upload như nào cho an toàn với hệ thống, Yii2 cung cấp khá nhiều các Rule cho việc upload File để làm tăng việc an toàn khi file được upload lên server. Để tham khảo thêm các đồng dev có thể xem qua tại đây.