php – How to upload a file to directory in yii2?-ThrowExceptions

Exception or error:

i have an ActiveForm, and i want to add a field where the user can upload their photos.
the problem is that i don’t have an attribute for the image in the users table and every
input field in ‘yii’ expects a model and an attribute as follows.

<?= $form->field($model, 'attribute')->input($platforms) ?>

i don’t want to assign the image to any record nor i want to insert in in the database, i want it to be uploaded to a specific folder.

i have also checked the library kartik wrote, but also requires an attribute field.

How to solve:

Follow the official documentation

Form Model

namespace app\models;

use yii\base\Model;
use yii\web\UploadedFile;

* UploadForm is the model behind the upload form.
class UploadForm extends Model
 * @var UploadedFile|Null file attribute
public $file;

 * @return array the validation rules.
public function rules()
    return [
        [['file'], 'file'],

Form View

use yii\widgets\ActiveForm;

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

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


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


Now create the controller that connects form and model together:

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;

class SiteController extends Controller
public function actionUpload()
    $model = new UploadForm();

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

        if ($model->validate()) {                
            $model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);

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

Instead of model->load(...) we are using UploadedFile::getInstance(...). [[\yii\web\UploadedFile|UploadedFile]] does not run the model validation. It only provides information about the uploaded file. Therefore, you need to run validation manually via $model->validate(). This triggers the [[yii\validators\FileValidator|FileValidator]] that expects a file:

 $file instanceof UploadedFile || $file->error == UPLOAD_ERR_NO_FILE //in code framework

If validation is successful, then we’re saving the file:

 $model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);

If you’re using “basic” application template then folder uploads should be created under web.

That’s it. Load the page and try uploading. Uplaods should end up in basic/web/uploads.


in your view

use kartik\widgets\ActiveForm;
use kartik\widgets\FileInput;

$form = ActiveForm::begin(['options' => ['enctype'=>'multipart/form-data']]); //important
echo FileInput::widget([
                    'name' => 'filename',
                    'showUpload' => false,
                    'buttonOptions' => ['label' => false],
                    'removeOptions' => ['label' => false],
                    'groupOptions' => ['class' => 'input-group-lg']
echo Html::submitButton('Submit', ['class'=>'btn btn-primary']);

in your controller

$file = \yii\web\UploadedFile::getInstanceByName('filename');


Create a read only attribute for your model like public $imageand proceed like

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


I really like Yii2 Dropzone.


composer require --prefer-dist perminder-klair/yii2-dropzone "dev-master"


    echo \kato\DropZone::widget([
       'options' => [
           'url'=> Url::to(['resource-manager/upload']),
           'maxFilesize' => '10',
       'clientEvents' => [
           'complete' => "function(file){console.log(file)}",
           'removedfile' => "function(file){alert( + ' is removed')}"



public function actionUpload(){

        $model = new ResourceManager();
        $uploadPath = Yii::getAlias('@root') .'/uploads/';

        if (isset($_FILES['image'])) {
            $file = \yii\web\UploadedFile::getInstanceByName('image');
          $original_name = $file->baseName;  
          $newFileName = \Yii::$app->security
           // you can write save code here before uploading.
            if ($file->saveAs($uploadPath . '/' . $newFileName)) {
                $model->image = $newFileName;
                $model->original_name = $original_name;
                    echo \yii\helpers\Json::encode($file);
                    echo \yii\helpers\Json::encode($model->getErrors());

        else {
            return $this->render('upload', [
                'model' => $model,

        return false;


give this code after your uploaded code

  //save the path in DB..
                $model->file = 'uploads/'.$imageName.'.'.$model->file->extension;


If you have more than one file while uploading you must use foreach for that. And you should actual name of file in a column in table and a encrypted value of that name has to be stored to avoid duplicated in the directory.. Something like this..

$userdocs->document_name = UploadedFile::getInstances($userdocs, 'document_name');

foreach ($userdocs->document_name as $key => $file) {
  $img_name = Yii::$app->security->generateRandomString();
  $file->saveAs('user/business_files/' . $img_name . '.' . $file->extension);
  $images = $img_name . '.' . $file->extension;
  $userdocs->actual_name = $file->name;
  $userdocs->user_id = $user->id;
  $userdocs->document_name = $images;
  $userdocs = new UserDocs();

Here a random string is generated and it will be assign with the name of the document, and it will be stored in the table. The UserDocs is the model name.

Leave a Reply

Your email address will not be published. Required fields are marked *