laravel框架核心-反射、依赖注入、控制反转
首页->学习资料->编程语言->php教程->laravel 关键词: 发布时间:2023-02-07 20:11:33 浏览次数:762

为什么会有反射?

如果我们写了一个类A,在其它地方调用A,而A中又new了一个类B,假如我们中途需要将A中new的类B换成类C,则需要修改类A,如果调用的地方少,修改下问题不大,但如果很多地方调用的话,修改起来不方便,风险大,偶合也高;现在我们希望动态的处理这些依赖,那可以通过构建函数等方式将B注入A,A依赖B,则A依赖注入了B(也可能是C,D等。。。),如果控制传统的方式,在类内面new,那每次都要修改,假如依赖很多个,还得增加或减少,能不能做到动态处理这些依赖呢;可以,我们可以结合 namespace找到这个类文件,解析他获得他的类名,方法,属性,注释等,是不是就可以操作这个类了,这个解析就是反射;

php通过反射来实现依赖注入简单列子 (hu-rong.com)

以下文章很形象的描述了依赖注入与控制反转:

浅谈控制反转与依赖注入 - 知乎 (zhihu.com)

如果一个类A 的功能实现需要借助于类B,那么就称类B是类A的依赖,如果在类A的内部去实例化类B,那么两者之间会出现较高的耦合,一旦类B出现了问题,类A也需要进行改造,如果这样的情况较多,每个类之间都有很多依赖,那么就会出现牵一发而动全身的情况,程序会极难维护,并且很容易出现问题。要解决这个问题,就要把A类对B类的控制权抽离出来,交给一个第三方去做,把控制权反转给第三方,就称作控制反转(IOC Inversion Of Control)控制反转是一种思想,是能够解决问题的一种可能的结果,而依赖注入(Dependency Injection)就是其最典型的实现方法。由第三方(我们称作IOC容器)来控制依赖,把他通过构造函数、属性或者工厂模式等方法,注入到类A内,这样就极大程度的对类A和类B进行了解耦


laravel中的控制反转:

(3条消息) 理解laravel---1.2 控制反转2_zhuxineli的博客-CSDN博客

(3条消息) 理解laravel---1.3 控制反转3_zhuxineli的博客-CSDN博客

<?php
/**
 * author:hurong
 * website:http://www.hu-rong.com
 */


/**
 * @author zhuxinlei
 * @date 2020-06-12
 * @desc 我是类A的注释
 */
class A
{
    //我是构造函数的注释
    public function __construct(B $b)
    {
        $this->b = $b;
    }

    //我是getB的注释
    public function getB()
    {
        $this->b->bMethod();
    }
}

class B
{
    public function __construct(C $c, D $d)
    {
        $this->c = $c;
        $this->d = $d;
    }

    public function bMethod()
    {
        echo "我是B中的方法bMethod()";
    }
}

class C
{
    public function __construct()
    {

    }

    public function cMethod()
    {
        echo "我是C中的方法cMethod()";
    }

}

class D
{
    public function __construct()
    {

    }

    public function dMethod()
    {
        echo "我是D中的方法dMethod()";
    }
}

class Ioc
{
    protected $instances = [];

    public function __construct()
    {
    }

    public function getInstance($abstract)//$abstract string "A"
    {
        //获取类的反射信息,也就是类的所有信息
        //$reflector:object(ReflectionClass)#2 (1) { ["name"]=> string(1) "A" }
        $reflector = new ReflectionClass($abstract);
        //  echo $reflector->getDocComment();  获取类的注释信息

        //获取反射类的构造函数信息
        //object(ReflectionMethod)#3 (2) { ["name"]=> string(11) "__construct" ["class"]=> string(1) "A" }
        $constructor = $reflector->getConstructor();
        //获取反射类的构造函数的参数
        //array(1) { [0]=> object(ReflectionParameter)#4 (1) { ["name"]=> string(1) "b" } }
        $dependencies = $constructor->getParameters();


        if (!$dependencies) {
            return new $abstract();
        }
        foreach ($dependencies as $dependency) {
            //$dependency:object(ReflectionParameter)#4 (1) { ["name"]=> string(1) "b" }
            if (!is_null($dependency->getClass())) {
                //$dependency->getClass:object(ReflectionClass)#5 (1) { ["name"]=> string(1) "B" }
                //$dependency->getClass->name: string(1) "B"
                $p[] = $this->make($dependency->getClass()->name);
                //这里$p[0]是C的实例化对象,$p[1]是D的实例化对象
            }
        }
        //创建一个类的新实例,给出的参数将传递到类的构造函数
        /**
         * $p
         *Array
         * (
         * [0] => C Object
         * (
         * )
         *
         * [1] => D Object
         * (
         * )
         *
         * )
         * Array
         * (
         * [0] => B Object
         * (
         * [c] => C Object
         * (
         * )
         *
         * [d] => D Object
         * (
         * )
         *
         * )
         *
         * )
         * )
         */
        /**
         * $reflector->newInstanceArgs($p)
         *
         * B Object
         * (
         * [c] => C Object
         * (
         * )
         *
         * [d] => D Object
         * (
         * )
         *
         * )
         * A Object
         * (
         * [b] => B Object
         * (
         * [c] => C Object
         * (
         * )
         *
         * [d] => D Object
         * (
         * )
         *
         * )
         *
         * )
         */
        //ReflectionClass::newInstanceArgs - 从给出的参数创建一个新的类实例。
        return $reflector->newInstanceArgs($p);
    }


    public function make($abstract)
    {
        return $this->getInstance($abstract);
    }
}

$ioc = new Ioc();
$a = $ioc->make('A');
$a->getB();


赞:(0)
踩:(0)
相关文章
laravel 中悲观锁 & 乐观锁的使用
laravel整合dingo/api方法步骤:jwt
一个简单的laravel分表联合查询
laravel页面静态化的方法
laravel对具体的路由不采用csrfTok
laravel不转义富文本中html标签
laravel学习笔记
laravel监听sql并生成日志,php art
laravel框架核心-serviceProvider
laravel启动流程(生命周期)
热门文章
win7中将文件拷贝到虚拟机linux下
phpexcel设置行高及列宽,背景颜色,
rabbitmq无法启动
intellij idea不显示git push按钮
php7中使用mongodb的aggregate进行
centos7.4 64位下swoole安装及配置
laravel页面静态化的方法
navicate连接mycat报1184错误
单点登录sso原理及php实现方式及de
devops-jenkins容器为pending状态
好评文章
phpexcel设置行高及列宽,背景颜色,
php7中使用mongodb的aggregate进行
intellij idea打开文件所在文件夹
windows下使用MongoDB Compass Com
win7中将文件拷贝到虚拟机linux下
laravel 中悲观锁 & 乐观锁的使用
单点登录sso原理及php实现方式及de
navicate连接mycat报1184错误
rabbitmq无法启动
laravel整合dingo/api方法步骤:jwt
标签
rabbitmq mysql备份 elasticsearch golang swoole
我的项目
【github】www.github.com/hurong241
【码云】gitee.com/hu_rong/projects
【docker hub】hub.docker.com/repositories/hurong241
【packagist】packagist.org/users/hurong241/packages
站点信息
建站时间:2011年
文章数:607篇
浏览数:942448
粤ICP备18028092号-1  微信:hurong241