「本文將實作一個簡單的容器類別
」
此時如果還是直接執行dependency路由就會報下邊一個錯,那是因為在Person中建構函式有個參數,的但是我們沒有傳。
此時就需要在修改一處,就是在實例化Person時把Car的實例當參數傳進去就沒有任何問題了。
但是你會發現上邊這都是什麼程式碼,原本簡簡單單的幾行程式碼被複雜成這個樣子,這時候就已經弊大於利了,不管設計模式在好,盲目的使用對專案來說也是一種負擔。所以這時候反射就來了,反射在上文中也進行簡單的介紹過,一定要看哈!文章都是一環套著一環的。
反射之戰優化程式碼
最終優化完成的程式碼就是這樣的,接下來對這段程式碼進行簡單的解析。
kaka/container/Container.php
這個類別裡邊的get方法<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><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;"><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] => container\dependency\Car<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;">// container\dependency\Car</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/></code>
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中文網其他相關文章!