如果一个接口需要同时接受很多上传的东西。比如有视频,图片,txt等。我们再调用的时候这样写

$request = $this->request();
$files = $request->getSwooleRequest()->files;
/*获取传参的健 video | image*/
$types = array_keys($files);
$this->type = $types[0];
if ($types[0] == 'video') {
    $obj = new Video($request);
    $file = $obj->upload();
} else if ($types[0] = 'image') {
    $obj = new Image($request);
    $file = $obj->upload();
}

如果再有新的文件类型。比如txt.world等等。我们就得去修改业务层的代码逻辑加上一堆的else if.所以这种写法很不利于维护也不优雅
当然了也可以用这种发放替代

$namespase = 'use App\Lib\Upload\\' . ucfirst($types[0]);
new $namespase->upload();

但是如果你有其他的配置不在Upload下呢?所以这里我们用反射机制的思想来优化代码
Lib下创建ClassArr.php

namespace App\Lib;

/*反射机制有关的处理*/

class ClassArr
{
    public function uploadClassStat()
    {
        return [
            'video' => 'use App\Lib\Upload\Video',
            'image' => 'use App\Lib\Upload\Image',
        ];
    }
    /*
     * $type是ClasStat里的存在的健。
     * $supportedClass是一个数组就是ClassStat的数组
     * $paramas是一个数组 比如上传文件的base.__construct($request) 就相当于$request
     * $needInstance 是否需要实例化,默认需要
     * 有些类是不需要示例化的。如静态类
     * */
    public function initClass($type, $supportedClass, $params = [], $needInstance = true)
    {
        if (!array_key_exists($type, $supportedClass)) {
            return false;
        }
        $className = $supportedClass[$type];
        /*
         * 如果$reendInstance == true 就示例化这个类
         * 然后调用他下面的
         * */
        return $needInstance ? (new \ReflectionClass($className))->newInstanceArgs($params): $className;

    }
}

如果有新的上传类型我们就可以直接在uploadClassStat下面加了。
调用的时候就直接

try {
    $request = $this->request();
    $files = $request->getSwooleRequest()->files;
    //获取传参的健 video | image
    $types = array_keys($files);
    $this->type = $types[0];
    $obj = new ClassArr();
    $uploadClass = $obj->uploadClassStat();
    $uploadObj = $obj->initClass($this->type,$uploadClass,[$request,$this->type]);
    $file = $uploadObj->upload();
} catch (\Exception $e) {
    return $this->writeJson(400, $e->getMessage());
}
if (empty($file)) {
    return $this->writeJson(400, '上传失败');
}
$data = [
    'url' => $file
];
return $this->writeJson(200, 'ok', $data);

我们在这里已经获取了文件的健名.所以我们就不需要在Base里在获取了所以这里也可以优化一下

public function __construct($request,$type=null)
{
    $this->request = $request;
    if(empty($type)){
        $files = $request->getSwooleRequest()->files;
        /*获取传参的健 video | image*/
        $types = array_keys($files);
        $this->type = $types[0];
    }else{
        $this->type = $type;
    }
}

ok!经过测试还是成功的.这里只是一个思想。让代码更优雅.更容易去维护.在出现要修改的地方也不需要直接在业务层添加代码.

Last modification:February 18th, 2020 at 10:34 pm