• 技术文章 >php框架 >ThinkPHP

    ThinkPHP之玩转自己的容器类

    咔咔咔咔2020-10-12 13:57:59原创79

    本文将实现一个简单的容器类

    五、玩转自己的容器类

    此时我们把Person 的文件修改一下

    添加一个构造函数,把参数使用构造函数进行赋值,在buy方法中就不需要在进行传递参数,只需要使用this->obj即可。

    在这里插入图片描述此时如果还是直接运行dependency路由就会报下边一个错,那是因为在Person中构造函数有个参数,的但是我们没有传。

    在这里插入图片描述此时就需要在修改一处,就是在实例化Person时把Car的实例当参数给传进去就没有任何问题了。

    在这里插入图片描述
    在这里插入图片描述

    但是你会发现上边这都是什么代码,本来简简单单的几行代码被复杂成这个样子,这个时候就已经弊大于利了,不管设计模式在好,盲目的使用对项目来说也是一种负担。

    所以这个时候反射就来了,反射在上文中也进行简单的介绍过,一定要看哈!文章都是一环套着一环的。

    反射之战优化代码

    最终优化完成的代码就是这样的,接下来对这段代码进行简单的解析。

    • 在之前代码的基础上只修改了kaka/container/Container.php这个类里边的get方法
    • 判断这个名person是否在容器中
    • 使用反射接口,然后获取传进去person类的构造方法
    • 如果person没有构造方法就直接返回person这个实例即可
    • 如存person在构造函数,则获取person构造函数的方法
    • 由于person类里边的构造函数的参数不会仅限于一个
    • 所以需要循环来获取每个参数的对象
    • 最后使用反射的 newInstanceArgs接口创建对应的实例
    <?php
    /**
    * Created by PhpStorm.
    * User: 咔咔
    * Date: 2020/9/21
    * Time: 19:04
    */


    namespace container;


    class Container
    {
    /**
    * 存放容器
    * @var array
    */

    public $instances = [];

    /**
    * 容器的对象实例
    * @var array
    */

    protected static $instance;

    /**
    * 定义一个私有的构造函数防止外部类实例化
    * Container constructor.
    */

    private function __construct() {

    }

    /**
    * 获取当前容器的实例(单例模式)
    * @return array|Container
    */

    public static function getInstance ()
    {
    if(is_null(self::$instance)){
    self::$instance = new self();
    }

    return self::$instance;
    }

    public function set ($key,$value)
    {
    return $this->instances[$key] = $value;
    }

    /**
    * User : 咔咔
    * Notes: 获取容器里边的实例 使用反射
    * Time :2020/9/21 22:04
    * @param $key
    * @return mixed
    */

    public function get ($key)
    {
    if(!empty($this->instances[$key])){
    $key = $this->instances[$key];
    }

    $reflect = new \ReflectionClass($key);
    // 获取类的构造函数
    $c = $reflect->getConstructor();
    if(!$c){
    return new $key;
    }

    // 获取构造函数的参数
    $params = $c->getParameters();
    foreach ($params as $param) {
    /**
    ReflectionClass Object
    (
    [name] => container\dependency\Car
    )
    */

    $class = $param->getClass();
    if(!$class){

    }else{
    // container\dependency\Car
    $args[] = $this->get($class->name);
    }
    }
    // 从给出的参数创建一个新的类实例
    return $reflect->newInstanceArgs($args);
    }
    }

    在这里插入图片描述文件application/index/controller/Container.php这里就是修改之后的变动

    在这里插入图片描述问题一:kaka/container/dependency/Person.php里边的参数Car是什么意思

    这个问题其实很简单,你可以看到这个Car就是同目录的Car.php文件。你就可以直接理解为同命名空间下的文件。

    在这里插入图片描述问题二:文件application/index/controller/Container.php为什么可以直接调用buy方法

    首先看一下obj的值,返回的这个对象里边就已经把Car的类实例化好了,所以无需在实例化,可直接调用buy方法,因为参数会直接传递过去

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述以上就是咔咔实现的一个简单的容器,如有不明白或者问题可以直接评论区回复即可。

    接下来就是针对框架里边的容器进行剖析,一步一步的追溯到根源。

    坚持学习、坚持写博、坚持分享是咔咔从业以来一直所秉持的信念。希望在偌大互联网中咔咔的文章能带给你一丝丝帮助。我是咔咔,下期见。

    以上就是ThinkPHP之玩转自己的容器类的详细内容,更多请关注php中文网其它相关文章!

    本文原创发布php中文网,转载请注明出处,感谢您的尊重!
    专题推荐:ThinkPHP
    上一篇:ThinkPHP容器之使用设计模式和反射实现一个简单的案例 下一篇:ThinkPHP容器之Countable巧用
    第13期线上培训班

    相关文章推荐

    • ThinkPHP容器之注册树模式• ThinkPHP容器之控制反转和依赖注入• ThinkPHP容器之反射机制• ThinkPHP容器之使用设计模式和反射实现一个简单的案例

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网