“
本文将实现一个简单的容器类
”
五、玩转自己的容器类
此时我们把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中文网如有侵权请联系admin#tyuanma.cn删除
本文永久链接地址:https://www.ymkuzhan.com/455.html