首頁 >php框架 >ThinkPHP >ThinkPHP之玩轉自己的容器類

ThinkPHP之玩轉自己的容器類

咔咔
咔咔原創
2020-10-12 12:24:071958瀏覽

本文將實作一個簡單的容器類別

##五、玩轉自己的容器類別

此時我們把Person 的檔案修改一下

新增一個建構函數,把參數使用建構子進行賦值,在buy方法中就不需要在進行傳遞參數,只要使用this->obj即可。

此時如果還是直接執行ThinkPHP之玩轉自己的容器類dependency路由就會報下邊一個錯,那是因為在Person中建構函式有個參數,的但是我們沒有傳。

此時就需要在修改一處,就是在實例化Person時把Car的實例當參數傳進去就沒有任何問題了。 ThinkPHP之玩轉自己的容器類

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><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.phpThinkPHP之玩轉自己的容器類這裡就是修改之後的變動

問題一:ThinkPHP之玩轉自己的容器類kaka/container/dependency/Person.php裡邊的參數Car是什麼意思這個問題其實很簡單,你可以看到這個Car就是同目錄的Car.php檔。你就可以直接理解為同命名空間下的檔案。

ThinkPHP之玩轉自己的容器類問題二:檔案application/index/controller/Container.php為什麼可以直接呼叫buy方法

先看一下obj的值,傳回的這個物件裡邊就已經把Car的類別實例化好了,所以不需要在實例化,可直接呼叫buy方法,因為參數會直接傳遞過去

ThinkPHP之玩轉自己的容器類
在這裡插入圖片描述

ThinkPHP之玩轉自己的容器類以上就是咔咔實現的一個簡單的容器,如有不明白或問題可以直接評論區回复即可。

接下來就是針對框架裡邊的容器進行剖析,一步一步的追溯到根源。

堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。希望在偌大互聯網中咔咔的文章能帶給你一絲絲幫助。我是咔咔,下期見。

以上是ThinkPHP之玩轉自己的容器類的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn