如何为Yii2创建文件上载REST API控制器

时间:2016-05-02 11:40:49

标签: php api ionic-framework yii2

我正在使用Ionic框架进行移动应用开发。下面的Yii2 API代码可用于文件上传,但它不起作用。它显示以下错误:

  

i)未定义的偏移量:0。

     

ii)yii \ db \ BaseActiveRecord-> save()

public function actionNew() {
    $model = new Apiprofile();
    $userid = $_REQUEST['user_id'];
    $photo = $_FILES['photo'];
    $model->user_id = $userid;
    $model->photo = $photo;
    $name = $model->user_id;
    $model->file = UploadedFile::getInstance($model, 'photo');

    if($model->file) {
        $model->file->saveAs('uploads/photos/'.$name.'.'.$model->file->extension);
        $model->photo = $name.'.'.$model->file->extension;
        $model->save();
    }

    $name = $model->user_id;

    if($model->save()) {
        echo json_encode(array('status'=>1,'data'=>$model->attributes),JSON_PRETTY_PRINT);
    } else {
        echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
    }
}

1 个答案:

答案 0 :(得分:0)

您好,如果您愿意,我将分享我在Yii2 REST中处理图像所使用的助手类。

在应用程序的基本文件夹中,创建文件夹组件并在该文件夹内创建两个文件夹助手和对象。

 -->assets
    -->componests
            ----->helpers
            ----->objects
    -->config
    -->...

之后在对象文件夹中创建类FileUpload并将此代码放入其中。

<?php
namespace app\components\objects;


class FileUpload
{
    public $error=[];
    public $isSuccess=false;
    public $file;
    public $ready_path;
    public $file_type;
    public $file_size;
    public $file_extension;
    public $file_tmp_name;

    public $file_name;
    public $save_path;

    public function __construct($file,$save_path,$ready_path,$required=false)
    {
        if(!isset($_FILES[$file])){
            if($required){
                $this->error=['message'=>$file.' is required'];
            }
            return $this;
        }
        $this->save_path=$save_path;
        $this->ready_path=$ready_path;
        $this->file_type = strtolower($_FILES[$file]['type']);
        $this->file_name = $_FILES[$file]['name'];
        $this->file_tmp_name=$_FILES[$file]['tmp_name'];
        $this->file_size = $_FILES[$file]['size'];
        $this->file_extension=pathinfo($this->file_name, PATHINFO_EXTENSION);
    }

    public function setError($error){
        if(empty($this->error)){
            $this->error=$error;
        }
    }

}

然后在helpers文件夹中创建类FileUploadHelper,然后将此代码放入其中。

<?php
namespace app\components\helpers;
use app\components\objects\FileUpload;
use Yii;

class  FileUploadHelper
{

    private $allowed_files;
    private $file_size;
    const IMAGE='image';
    const FILE='file';

    /** File Upload
     * @param string $file_name
     * @param string $save_path
     * @param string $ready_path
     * @param string $type
     * @param bool $required

     * @return \app\components\objects\FileUpload
     */
    public static function fileUpload($file_name,$save_path,$ready_path,$type,$required=false){

        $image=new FileUpload($file_name,$save_path,$ready_path,$required);
        if($type==self::FILE){
            $allowed_files=Yii::$app->params['allowed_files'];
            $file_size=Yii::$app->params['file_max_size'];
        }else{
            $allowed_files=Yii::$app->params['allowed_files'];
            $file_size=Yii::$app->params['file_max_size'];
        }
        $dir = realpath(Yii::$app->basePath);
        if(in_array($image->file_type,$allowed_files)
            &&$image->file_size<$file_size){
            $filename = $file_name.'_'.md5(uniqid(time()).time() . '_' . date('YmdHis')) . '.' . $image->file_extension;
            $file = $dir . $image->save_path . $filename;
            if(move_uploaded_file($image->file_tmp_name, $file)){
                $image->file=$image->ready_path. $filename;
                $image->isSuccess=true;
                $image->setError(['message'=>'file_upload_success']);
            }else{
                $image->setError(['message'=>'error_try_again']);
            }
        }else{
            $image->setError(['message'=>'file_should_be_no_more_than_given_size']);
        }
        return $image;
    }


    /** Delete File
     * @param string $ready_file
     */
    public static function deleteImage($ready_file){
        $dir = realpath(Yii::$app->basePath);
        if (strpos($ready_file, 'default') === false){
            if(is_file($dir.'/web/'.$ready_file)){
                unlink($dir.'/web/'.$ready_file);
            }
        }
    }
}

这就是全部所需要的。下面我将举例说明

public function actionEditAvatar($id)
    {
        $product = Product::findOne($id);
        if( $product ){
                $old_avatar=$product->avatar;
                $image=FileUploadHelper::fileUpload(ProductForm::AVATAR,Yii::$app->params['product_path'],Yii::$app->params['product_ready_path'],FileUploadHelper::IMAGE);
                if($image->isSuccess) {
                    $product->avatar = $image->file;
                    if($product->save()){
                        FileUploadHelper::deleteImage($old_avatar);
                        return $product->avatar;
                    }

                }
            return $image->error;
        }
        throw new NotFoundHttpException;
    }

上面的代码来自一个真实的项目。 FileUploadHelper有两个静态类,分别是“fileUpload”和“deleteImage”。 FileUploadHelper需要fileUpload('file_name','save_path','ready_path','type') 'save_path'是文件的保存位置。 'ready_path'是准备好的URL的样子。 它们在Yii :: $ app-&gt; params [];

您可以通过属性isSuccess检查图像是否成功。如果您有错误,可以通过属性错误访问它们。可以通过属性文件访问就绪文件。你可以通过静态函数deleteImage删除图像('saved_image_url');所有这些都用于上述动作。请看看。 顺便说一句,这里是我使用的参数。不要忘记在web / uploads中创建文件夹,并在配置文件中更改文件夹的名称。

return [
    'adminEmail' => 'admin@example.com',

    'allowed_images'                   => [ 'image/jpeg', 'image/gif', 'image/png' ],
    'allowed_files'                    => [ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/msword', 'application/pdf','image/jpeg', 'image/gif', 'image/png'],

    'image_max_size'                   => 2097152,
    'file_max_size'                    => 8388608,

    'owner_document_path'              => '/web/uploads/owner_document/',
    'owner_document_ready_path'        => 'uploads/owner_document/',

    'product_path'                     => '/web/uploads/product/',
    'product_ready_path'               => 'uploads/product/',

    'complain_photo_path'              => '/web/uploads/complain_photo/',
    'complain_photo_ready_path'        => 'uploads/complain_photo/',

    'owner_path'                       => '/web/uploads/owner/',
    'owner_ready_path'                 => 'uploads/owner/',


    'staff_path'                       => '/web/uploads/staff/',
    'staff_ready_path'                 => 'uploads/staff/',
];