“
在之前的文章中我們簡單的梳理了一下容器類,接下來就是對其中一個細節進行深度分析。
”
Container實例調用make方法
本文沒有太多文字解析,都在代碼注釋中說明了執行過程。
代碼Static::getInstance()返回了Container的實例后,就會去調用本類的make方法,接下來就是對make方法進行詳解了。
在開始閱讀make方法里邊的源碼之前,我們需要先對幾個屬性進行簡單的梳理一下。
這四個屬性一定要有點印象,并且一定要區別instance和instances。
這倆個屬性一個是單例模式返回當前類的實例,一個是容器中的所有的實例。
第一次執行結果
<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-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br>?????*?創建類的實例<br>?????*?<span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@access</span>?public<br>?????*?<span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@param</span>??string????????$abstract???????類名或者標識<br>?????*?<span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@param</span>??array|true????$vars???????????變量<br>?????*?<span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@param</span>??bool??????????$newInstance????是否每次創建新的實例<br>?????*?<span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@return</span>?object<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;">make</span><span class="hljs-params" style="line-height: 26px;">($abstract,?$vars?=?[],?$newInstance?=?false)</span><br>????</span>{<br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?判斷$vars這個變量是否為true</span><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span>?===?$vars)?{<br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?總是創建新的實例化對象</span><br>????????????$newInstance?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span>;<br>????????????$vars????????=?[];<br>????????}<br><br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?app??這里就是在容器別名里獲取傳遞過來的app????如果沒有則就是app</span><br>????????$abstract?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract])???<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract]?:?$abstract;<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;">if</span>?(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract])?&&?!$newInstance)?{<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[$abstract];<br>????????}<br><br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?thinkApp?從容器標識中獲取</span><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract]))?{<br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?將thinkApp?復制給$concrete變量</span><br>????????????$concrete?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract];<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;">if</span>?($concrete?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">instanceof</span>?Closure)?{<br>????????????????$object?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeFunction($concrete,?$vars);<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;">//?$this->name['app']?=?thinkApp</span><br>????????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract]?=?$concrete;<br>????????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?在執行一次本類的make方法,也就是本方法</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>->make($concrete,?$vars,?$newInstance);<br>????????????}<br>????????}?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">else</span>?{<br>????????????$object?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeClass($abstract,?$vars);<br>????????}<br><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?(!$newInstance)?{<br>????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract]?=?$object;<br>????????}<br><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span>?$object;<br>????}<br>
這是第二次執行流程
<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-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;">make</span><span class="hljs-params" style="line-height: 26px;">($abstract,?$vars?=?[],?$newInstance?=?false)</span><br>????</span>{<br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?判斷$vars這個變量是否為true</span><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span>?===?$vars)?{<br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?總是創建新的實例化對象</span><br>????????????$newInstance?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span>;<br>????????????$vars????????=?[];<br>????????}<br><br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?app??這里就是在容器別名里獲取傳遞過來的app????如果沒有則就是app</span><br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?第二次執行時?$abstract?=?thinkApp</span><br>????????$abstract?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract])???<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract]?:?$abstract;<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;">if</span>?(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract])?&&?!$newInstance)?{<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[$abstract];<br>????????}<br><br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?thinkApp?從容器標識中獲取</span><br>????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?第二次執行$this->bind['thinkApp']不存在走else</span><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract]))?{<br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?將thinkApp?復制給$concrete變量</span><br>????????????$concrete?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract];<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;">if</span>?($concrete?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">instanceof</span>?Closure)?{<br>????????????????$object?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeFunction($concrete,?$vars);<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;">//?$this->name['app']?=?thinkApp</span><br>????????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract]?=?$concrete;<br>????????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?在執行一次本類的make方法,也就是本方法</span><br>????????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?thinkApp</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>->make($concrete,?$vars,?$newInstance);<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;">//?thinkApp</span><br>????????????$object?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeClass($abstract,?$vars);<br>????????}<br><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?(!$newInstance)?{<br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?把創建的容器存起來</span><br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//$this->instances['thinkApp']?=?$object;</span><br>????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract]?=?$object;<br>????????}<br><br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span>?$object;<br>????}<br>
<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-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;">invokeClass</span><span class="hljs-params" style="line-height: 26px;">($class,?$vars?=?[])</span><br>????</span>{<br>????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">try</span>?{<br><br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br>?????????????*?ReflectionClass?Object<br>????????????????(<br>????????????????[name]?=>?thinkApp<br>????????????????)<br>?????????????*/</span><br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?這里就是之前文章提到的反射</span><br>????????????$reflect?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span>?ReflectionClass($class);<br><br><br>????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?($reflect->hasMethod(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'__make'</span>))?{<br>????????????????$method?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span>?ReflectionMethod($class,?<span class="hljs-string" style="color: #98c379; line-height: 26px;">'__make'</span>);<br><br>????????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span>?($method->isPublic()?&&?$method->isStatic())?{<br>????????????????????$args?=?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bindParams($method,?$vars);<br>????????????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span>?$method->invokeArgs(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">null</span>,?$args);<br>????????????????}<br>????????????}<br>????????????<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//?通過反射獲取thinkApp的構造函數</span><br>????????????$constructor?=?$reflect->getConstructor();<br><br>????????????$args?=?$constructor???<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bindParams($constructor,?$vars)?:?[];<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>????????}?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">catch</span>?(ReflectionException?$e)?{<br>????????????<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">throw</span>?<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span>?ClassNotFoundException(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'class?not?exists:?'</span>?.?$class,?$class);<br>????????}<br>????}<br>
執行流程圖
既然把代碼都理清楚了,這時來理一下執行的流程圖可以看的更清晰。
“
堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。希望在偌大互聯網中咔咔的文章能帶給你一絲絲幫助。我是咔咔,下期見。
”
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END