反射之战优化代码
最终优化完成的代码就是这样的,接下来对这段代码进行简单的解析。
- 在之前代码的基础上只修改了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方法,因为参数会直接传递过去
以上就是咔咔实现的一个简单的容器,如有不明白或者问题可以直接评论区回复即可。
接下来就是针对框架里边的容器进行剖析,一步一步的追溯到根源。
六、Container容器类剖析之Countable巧用
关于Countable这块内容一直没想好是否是文章的形式写出展现给大家,但是在后期阅读源码时大量的出现了Countable的应用。
为了大家能看懂每一个技术点,咔咔还是写了出来。
在文件thinkphp/library/think/Container.php中,就可以直接看到使用了Countable接口,并且实现了它!
来到Countable这接口中,我们只能看到一个方法就是count().
根据代码中Count elements of an object这行注释可以了解到,这个接口是计算对象的元素
根据PHP文档的说明在深入了解一下。
文档说明当你执行count()方法时就相当于在执行上边的abstract public Countable::count ( void ) : int抽象方法。