“
本文将实现一个简单的容器类
”
五、玩转自己的容器类
此时我们把Person 的文件修改一下
添加一个构造函数,把参数使用构造函数进行赋值,在buy方法中就不需要在进行传递参数,只需要使用this->obj即可。
此时如果还是直接运行dependency路由就会报下边一个错,那是因为在Person中构造函数有个参数,的但是我们没有传。
此时就需要在修改一处,就是在实例化Person时把Car的实例当参数给传进去就没有任何问题了。
但是你会发现上边这都是什么代码,本来简简单单的几行代码被复杂成这个样子,这个时候就已经弊大于利了,不管设计模式在好,盲目的使用对项目来说也是一种负担。
所以这个时候反射就来了,反射在上文中也进行简单的介绍过,一定要看哈!文章都是一环套着一环的。
反射之战优化代码
最终优化完成的代码就是这样的,接下来对这段代码进行简单的解析。
-
在之前代码的基础上只修改了kaka/container/Container.php这个类里边的get方法 -
判断这个名person是否在容器中 -
使用反射接口,然后获取传进去person类的构造方法 -
如果person没有构造方法就直接返回person这个实例即可 -
如存person在构造函数,则获取person构造函数的方法 -
由于person类里边的构造函数的参数不会仅限于一个 -
所以需要循环来获取每个参数的对象 -
最后使用反射的 newInstanceArgs接口创建对应的实例
<span style="display: block; background: url(https://my-wechat.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><span class="hljs-meta" style="color: #61aeee; line-height: 26px;"><?php </span><br><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br> * Created by PhpStorm.<br> * User: 咔咔<br> * Date: 2020/9/21<br> * Time: 19:04<br> */</span><br><br><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">namespace</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">container</span>;<br><br><br><span class="hljs-class" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">class</span> <span class="hljs-title" style="color: #e6c07b; line-height: 26px;">Container</span><br></span>{<br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br> * 存放容器<br> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@var</span> array<br> */</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">public</span> $instances = [];<br><br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br> * 容器的对象实例<br> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@var</span> array<br> */</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">protected</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">static</span> $instance;<br><br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br> * 定义一个私有的构造函数防止外部类实例化<br> * Container constructor.<br> */</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">private</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">__construct</span><span class="hljs-params" style="line-height: 26px;">()</span> </span>{<br><br> }<br><br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br> * 获取当前容器的实例(单例模式)<br> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@return</span> array|Container<br> */</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">public</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">static</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">getInstance</span> <span class="hljs-params" style="line-height: 26px;">()</span><br> </span>{<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>(is_null(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">self</span>::$instance)){<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">self</span>::$instance = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">self</span>();<br> }<br><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">self</span>::$instance;<br> }<br><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">public</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">set</span> <span class="hljs-params" style="line-height: 26px;">($key,$value)</span><br> </span>{<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$key] = $value;<br> }<br><br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br> * User : 咔咔<br> * Notes: 获取容器里边的实例 使用反射<br> * Time :2020/9/21 22:04<br> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@param</span> $key<br> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@return</span> mixed<br> */</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">public</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">get</span> <span class="hljs-params" style="line-height: 26px;">($key)</span><br> </span>{<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>(!<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">empty</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$key])){<br> $key = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$key];<br> }<br><br> $reflect = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span> ReflectionClass($key);<br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 获取类的构造函数</span><br> $c = $reflect->getConstructor();<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>(!$c){<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span> $key;<br> }<br><br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 获取构造函数的参数</span><br> $params = $c->getParameters();<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">foreach</span> ($params <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">as</span> $param) {<br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br> ReflectionClass Object<br> (<br> [name] => containerdependencyCar<br> )<br> */</span><br> $class = $param->getClass();<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>(!$class){<br><br> }<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">else</span>{<br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// containerdependencyCar</span><br> $args[] = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->get($class->name);<br> }<br> }<br> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 从给出的参数创建一个新的类实例</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> $reflect->newInstanceArgs($args);<br> }<br>}<br></span>
文件application/index/controller/Container.php这里就是修改之后的变动
问题一:kaka/container/dependency/Person.php里边的参数Car是什么意思
这个问题其实很简单,你可以看到这个Car就是同目录的Car.php文件。你就可以直接理解为同命名空间下的文件。
问题二:文件application/index/controller/Container.php为什么可以直接调用buy方法
首先看一下obj的值,返回的这个对象里边就已经把Car的类实例化好了,所以无需在实例化,可直接调用buy方法,因为参数会直接传递过去
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END