视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
ThinkPHP之玩转自己的容器类
2020-11-02 18:02:22 责编:小采
文档


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

五、玩转自己的容器类

此时我们把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] => containerdependencyCar
    )
    */
    $class = $param->getClass();
    if(!$class){

    }else{
    // containerdependencyCar
    $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方法,因为参数会直接传递过去

    在这里插入图片描述

    以上就是咔咔实现的一个简单的容器,如有不明白或者问题可以直接评论区回复即可。

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

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

    下载本文
    显示全文
    专题