Yii2 POST image to model in API without Yii2 Naming convention

萝らか妹 提交于 2019-12-24 09:57:47

问题


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.'];
    }
}

Postman


回答1:


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:

  1. Change the name you use to send your image file to follow the same naming conveniton. However you don't seem to want that.
  2. Use getInstanceByName('image') method instead of getInstance($model, 'image')



回答2:


The problem come here When you send files via api they are not sent asynchronously. If you check

echo '<pre>';
 print_r($_FILES); //returns nothing 
 print_r($_POST["image"]);  //returns something
 echo '</pre>';
die;

One reason is that your controller extendsyii\web\controller which is not used by rest apis, extend yii\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

The form
 <?php $form = ActiveForm::begin(['options' => ['enctype' => 
  'multipart/form-data','id'=>'slider_form']]); ?>  //dont forget enctype

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

Then on the ajax post

 var formData = new FormData($('form#slider_form')[0].files);

$.post(
    href, //serialize Yii2 form 
    {other atributes ,formData:formData}
)

Then on the controller simply access via
$model->file =$_FILES["TblSlider"]; //here this depends on your form attributes check with var_dump($_FILES)
$file_tmp = $_FILES["TblSlider"]["tmp_name"]["file"];
        $file_ext = pathinfo($_FILES['TblSlider']['name']["file"], PATHINFO_EXTENSION);

        if(!empty($model->file)){

            $filename = strtotime(date("Y-m-d h:m:s")).".".$file_ext;

            move_uploaded_file($file_tmp, "../uploads/siteimages/slider/".$filename);
            ///move_uploaded_file($file_tmp, Yii::getAlias("@uploads/siteimages/slider/").$filename);
            $model->image = $filename;
        }

I hope this helps



来源:https://stackoverflow.com/questions/41223566/yii2-post-image-to-model-in-api-without-yii2-naming-convention

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!