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 分享