laravel依赖注入原理

下例为官方文档,来认识一下反射



function bar(Exception $a, &$b, $c) { }


$reflect = new ReflectionFunction('bar');
#$reflect object(ReflectionFunction)#1 (1) { ["name"]=> string(3) "bar" }




foreach ($reflect->getParameters() as $i => $param) {
 #循环的第一次输出param object(ReflectionParameter)#2 (1) { ["name"]=> string(1) "a" }

    printf(
        "-- Parameter #%d: %s {\n".
        "   Class: %s\n".
        "   Allows NULL: %s\n".
        "   Passed to by reference: %s\n".
        "   Is optional?: %s\n".
        "}\n",
        $i,
        $param->getName(),#得到参数名 a
        var_export($param->getClass(), 1),
        #$param->getClass()输出为ReflectionClass::__set_state(array(
   'name' => 'Exception',
))
        var_export($param->allowsNull(), 1), #参数是否可以为空,可以为空返回true;
        var_export($param->isPassedByReference(), 1),#如果参数是按引用传递,返回true;
        $param->isOptional() ? 'yes' : 'no'
    );
    exit;
}
?>

下例为laravel的依赖注入原理,代码来自https://phphub.org/topics/843

<?php

namespace Database;
use ReflectionMethod;

class Database
{

    protected $adapter;

    public function __construct ()
    {}

    public function test (MysqlAdapter $adapter)
    {
        $adapter->test();
    }
}

class MysqlAdapter
{

    public function test ()
    {
        echo "i am MysqlAdapter test";
    }
}

class app
{

    public static function run ($instance, $method)
    {
        if (! method_exists($instance, $method))

            return null;

        $reflector = new ReflectionMethod($instance, $method);
        #$reflector object(ReflectionMethod)#2 (2) { ["name"]=> string(4) "test" ["class"]=> string(17) "Database\Database" }

        $parameters = [
                    1
            ];
        foreach ($reflector->getParameters() as $key => $parameter)
        #此处获得$method方法的需要的参数
        #$parameter object(ReflectionParameter)#3 (1) { ["name"]=> string(7) "adapter" }
        {
          $class = $parameter->getClass();
            if ($class)
            {
                array_splice($parameters, $key, 0, [
                        new $class->name()
                ]);#根据$method需要的参数,通过$class->name获得此参数的类型,然后生成一个此类型的对象,$parameters的开头处插入MysqlAdapter类型的对象 即$parameters=[MysqlAdapter对象,1]
            }
        }
        call_user_func_array([
                $instance,
                $method
        ], $parameters);#调用$instance对象下的$method方法,将$parameters作为参数传递
    }
}

app::run(new Database(), 'test');

总结:使用反射的意义在于,当传入一个对象和此对象包含的方法时;laravel通过反射来获取到此方法的参数列表,同时获取到参数的具体类型,然后根据此类型,生成对应的对象,供方法使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值