ThinkPHP之玩转自己的容器类

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

五、玩转自己的容器类

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

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

ThinkPHP之玩转自己的容器类此时如果还是直接运行dependency路由就会报下边一个错,那是因为在Person中构造函数有个参数,的但是我们没有传。

ThinkPHP之玩转自己的容器类此时就需要在修改一处,就是在实例化Person时把Car的实例当参数给传进去就没有任何问题了。

ThinkPHP之玩转自己的容器类
在这里插入图片描述

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

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

反射之战优化代码

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

  • 在之前代码的基础上只修改了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>-&gt;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>-&gt;instances[$key])){<br>            $key = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>-&gt;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-&gt;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-&gt;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] =&gt; containerdependencyCar<br>            )<br>             */</span><br>            $class = $param-&gt;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>-&gt;get($class-&gt;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-&gt;newInstanceArgs($args);<br>    }<br>}<br></span>

ThinkPHP之玩转自己的容器类文件application/index/controller/Container.php这里就是修改之后的变动

ThinkPHP之玩转自己的容器类问题一:kaka/container/dependency/Person.php里边的参数Car是什么意思

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

ThinkPHP之玩转自己的容器类问题二:文件application/index/controller/Container.php为什么可以直接调用buy方法

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

ThinkPHP之玩转自己的容器类
在这里插入图片描述

ThinkPHP之玩转自己的容器类

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享