I'm creating an endpoint for a mobile application to send a image to the server. I'm posting the image with the POSTMAN extension for chrome. The image is in the $_FILES
variable, and named image
. How can I load this image into a model, or the UploadedFile
class? The $model->load(Yii::$app->request->post())
line does not correctly load the file, as it is not in Yii2's naming convention for forms.
It's currently returning:
{
"success": false,
"message": "Required parameter 'image' is not set."
}
Code
models\Image.php
<?php
namespace api\modules\v1\models;
use yii\base\Model;
use yii\web\UploadedFile;
class Image extends Model
{
/**
* @var UploadedFile
*/
public $image;
public function rules()
{
return [
[['image'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
$path = dirname(dirname(__FILE__)) . '/temp/';
if ($this->validate()) {
$this->image->saveAs($path . $this->image->baseName . '.' . $this->image->extension);
return true;
} else {
die(var_dump($this->errors));
return false;
}
}
}
controllers\DefaultController.php
<?php
namespace api\modules\v1\controllers;
use api\modules\v1\models\Image;
use yii\web\Controller;
use yii\web\UploadedFile;
use Yii;
class DefaultController extends Controller
{
public $enableCsrfValidation = false;
public function actionIndex()
{
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$model = new Image();
if (Yii::$app->request->isPost) {
if($model->load(Yii::$app->request->post()))
{
$model->image = UploadedFile::getInstance($model, 'image');
if ($model->upload()) {
// file is uploaded successfully
return ['success' => true, 'message' => 'File saved.'];
}
else return ['success' => false, 'message' => 'Could not save file.'];
}
else return ['success' => false, 'message' => 'Required parameter \'image\' is not set.'];
}
else return ['success' => false, 'message' => 'Not a POST request.'];
}
}
Your problem seems to be the name you are using to send the image file. Usually Yii2 uses names for form attributes like "ModelName[attributeName]" and you are sending your image file with the name "image"
There are 2 ways of fixing this:
getInstanceByName('image')
method instead ofgetInstance($model, 'image')
The problem come here When you send files via api they are not sent asynchronously. If you check
One reason is that your controller extends
yii\web\controller
which is not used by rest apis, extendyii\rest\controller
The other way to go about this is by using javascript formData when sending the post request
This is a way i handled a previous ajax post of an image probably itll give you a guideline
Then on the ajax post
I hope this helps