如果一个接口需要同时接受很多上传的东西。比如有视频,图片,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!经过测试还是成功的.这里只是一个思想。让代码更优雅.更容易去维护.在出现要修改的地方也不需要直接在业务层添加代码.
加油!