文章目录
原文件地址:http://www.piliku.com/2019/11/20/118
PHP5 具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释。
本文主要讲解反射API中的 ReflectionClass
类。
更多反射API查看官网
利用反射来实现依赖注入,自动加载类之间的依赖关系。这是本文重要点。
API:ReflectionClass 类
1.初始化 ReflectionClass 类
把类名传递给 ReflectionClass,初始化 ReflectionClass 类。
返回初始化完成后的 ReflectionClass 实例。
$upload = new ReflectionClass(Upload::class);
// Upload如有命名空间将返回完整空间
new \ReflectionClass(App\Lib\Upload)
返回值:
ReflectionClass Object ( [name] => Upload
)
//ReflectionClass Object ( [name] => App\Lib\Upload
)
2.创建一个新的类实例
ReflectionClass::newInstance
从指定的参数创建一个新的类实例
ReflectionClass::newInstanceArgs
从给出的参数创建一个新的类实例。
两者要注意区分。
$upload->newInstance(['video', 'new.gif']);
$upload->newInstanceArgs(['video', 'new.gif']);
分别返回:
Upload Object ( [type] => Array ( [0] => video [1] => new.gif ) [file] => p.jpg )
Upload Object ( [type] => video [file] => new.gif )
3.获取方法及参数
getConstructor()
获取已反射的类的构造函数。getMethods()
获取方法的数组,包括构造函数。getParameters()
获取已反射的类的方法参数,如果是获取getMethods()
的参数,则要循环获取。
注意:如果反射的类有继承关系,则获取的方法数组包括父类里的方法。
获取已反射的类的构造函数及参数
$image = new ReflectionClass(Image::class);
$image->getConstructor();
$image->getConstructor()->getParameters();
$image->getMethods();
分别返回
// 是继承父类的构造函数
ReflectionMethod Object
(
[name] => __construct
[class] => Upload
)
// 构造函数参数
Array
(
[0] => ReflectionParameter Object
(
[name] => type
)
[1] => ReflectionParameter Object
(
[name] => file
)
)
更多API请查看手册。
反射实现依赖注入(文件上传)
以下案例是我用easyswoole写的项目中一个图片和视频上传功能,现拆解出来一部分。
1.文件上传类
/**
* 文件上传基类
*/
class Upload
{
//表单提交时文件名(如video、image)
public $type = '';
//上传成功后的文件
public $file = '';
public function __construct($type = 'image', $file='p.jpg')
{
$this->type = $type;
$this->file = $file;
}
/**
* 文件上传
* 文件大小和类型校验、移动文件到指定路径
* 返回文件完整路径
*/
public function upload()
{
echo $this->type.'文件上传逻辑';
}
}
//图片上传
class Image extends Upload
{
//视频文件
public $fileType = 'image';
public $maxSize = 122;
//文件后缀
public $fileExtTypes = [
'png',
'jpg',
'jpeg',
'gif',
];
}
// 视频上传
class Video extends Upload
{
//视频文件
public $fileType = 'video';
public $maxSize = 122;
//文件后缀
public $fileExtTypes = [
'mp4',
'x-flv'
];
}
2.反射实现依赖注入
//反射实现依赖注入,自动加载
class ioc
{
/**
* 上传类组合 测试放这里
* @return array
*/
public function uploadClass()
{
return [
'image' => 'Image',
'video' => 'Video',
];
}
/**
* $type 上传文件名
* $supportedClass 要实例化的上传类
* array $params
* bool $needInstance 是否实例化
*/
public function make($type, $supportedClass, $params = [], $needInstance = true)
{
if (!array_key_exists($type, $supportedClass)) {
return false;
}
//类名
$className = $supportedClass[$type];
return $needInstance ? (new \ReflectionClass($className))->newInstanceArgs($params) : $className;
}
}
3.调用
// type是请求过来的参数
$type = 'video';
$obj = new ioc();
$uploadClassArr = $obj->uploadClass();
$obj = $obj->make($type, $uploadClassArr, [$type]);
$file = $obj->upload();
以上,一个简单的入门案例。