通过PHP反射实现自动依赖注入(easyswoole文件上传案例)


原文件地址: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.获取方法及参数

  1. getConstructor() 获取已反射的类的构造函数。
  2. getMethods() 获取方法的数组,包括构造函数。
  3. 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();

以上,一个简单的入门案例。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值