Model:

namespace app\models; class TestModel extends \yii\base\Model { public $myImage; public function rules() { return [ ['myImage', 'image', ], ]; } } 

Representation:

 use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $this object yii\web\View */ /* @var $form object yii\widgets\ActiveForm */ /* @var $model object app\models\TestModel */ $form = ActiveForm::begin(['enableClientValidation' => false, ]); echo $form->field($model, 'myImage')->fileInput(); echo Html::submitButton(); ActiveForm::end(); 

I have disabled client side validation:

 'enableClientValidation' => false, 

to check how the validator works on the server, since everything works fine on the client side; however, the validator does not work on the server, that is, skips any files? ...


Controller:

 namespace app\controllers; use Yii; use yii\web\UploadedFile; use app\models\TestModel; class TestController extends \yii\web\Controller { public function actionIndex() { $model = new TestModel(); if ( $model->load(Yii::$app->request->post()) && $model->validate() ) { die('Model is valid!'); } return $this->render('index', [ 'model' => $model, ]); } } 
  • one
    Does getimagesize on server work? - ilyaplot 2:53 pm
  • @ilyaplot, what is this method: what class? - Roman Grinyov
  • one
    In Yii, the getimagesize function is used for validation. If it doesn't work, then the validation for the images will not work. - ilyaplot
  • one
    Use, for example, beforeSave or afterSave to place the file in the right place. - ilyaplot
  • one
    If you want to use such a strange method as a double call to save, the second time you can call save (false) - ilyaplot

3 answers 3

So, as usual - inattention! And the reluctance to understand!


It's all about the controller ...

As you know, files on arrival to the server via PHP are not available in $_POST , but in $_FILES ... Therefore, in fact, we cannot load the model completely like this:

 $model->load(Yii::$app->request->post()); 

We need to load attributes that are files like this:

 $model->myImage = UploadedFile::getInstance($model, 'myImage'); 

So, before validation, you need to fully load the model:

 public function actionIndex() { $model = new TestModel(); if ($model->load(Yii::$app->request->post())) { $model->myImage = UploadedFile::getInstance($model, 'myImage'); if ($model->validate()) { die('Model is valid!'); } } return $this->render('index', [ 'model' => $model, ]); } 

I’ll add that you need to assign data to attributes (which are files) after calling $model->load() , because otherwise they will be overloaded (due to the fact that this attribute will also appear in the POST request, but empty) .

    Perhaps you should specify the file extensions. There is an example in the documentation :

     [ // checks if "primaryImage" is a valid image with proper size ['primaryImage', 'image', 'extensions' => 'png, jpg', 'minWidth' => 100, 'maxWidth' => 1000, 'minHeight' => 100, 'maxHeight' => 1000, ], ] 
    • Thank you, but it doesn't work on the server either - Roman Grinyov
    • @RomanGrinyov Please provide the code of your controller and model - NPreston
    • Corrected the question ... - Roman Grinyov 9:59 pm
    • Found the cause: see my answer. - Roman Grinyov

    Try using FileValidator:

     public function rules() { return [ [['imageFiles'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg', 'maxFiles' => 4], ]; } 

    More details can be found here: Input file upload

    • I found out the reason: see my answer. - Roman Grinyov