這篇文章主要介紹ThinkPHP容器之容器是如何返回實(shí)例的,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
成都創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括武川網(wǎng)站建設(shè)、武川網(wǎng)站制作、武川網(wǎng)頁制作以及武川網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,武川網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到武川省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
Container實(shí)例調(diào)用make方法
本文沒有太多文字解析,都在代碼注釋中說明了執(zhí)行過程。
代碼static::getInstance()
返回了Container的實(shí)例后,就會去調(diào)用本類的make方法,接下來就是對make方法進(jìn)行詳解了。
在開始閱讀make方法里邊的源碼之前,我們需要先對幾個(gè)屬性進(jìn)行簡單的梳理一下。
這四個(gè)屬性一定要有點(diǎn)印象,并且一定要區(qū)別instance和instances。
這倆個(gè)屬性一個(gè)是單例模式返回當(dāng)前類的實(shí)例,一個(gè)是容器中的所有的實(shí)例。
第一次執(zhí)行結(jié)果
/** * 創(chuàng)建類的實(shí)例 * @access public * @param string $abstract 類名或者標(biāo)識 * @param array|true $vars 變量 * @param bool $newInstance 是否每次創(chuàng)建新的實(shí)例 * @return object */ public function make($abstract, $vars = [], $newInstance = false) { // 判斷$vars這個(gè)變量是否為true if (true === $vars) { // 總是創(chuàng)建新的實(shí)例化對象 $newInstance = true; $vars = []; } // app 這里就是在容器別名里獲取傳遞過來的app 如果沒有則就是app $abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract; // 從容器實(shí)例中獲取 如果存在則直接返回對應(yīng)的實(shí)例 也就是使用注冊樹模式 if (isset($this->instances[$abstract]) && !$newInstance) { return $this->instances[$abstract]; } // think\App 從容器標(biāo)識中獲取 if (isset($this->bind[$abstract])) { // 將think\App 復(fù)制給$concrete變量 $concrete = $this->bind[$abstract]; // 用于代表匿名函數(shù)的類 判斷是不是閉包 if ($concrete instanceof Closure) { $object = $this->invokeFunction($concrete, $vars); } else { // $this->name['app'] = think\App $this->name[$abstract] = $concrete; // 在執(zhí)行一次本類的make方法,也就是本方法 return $this->make($concrete, $vars, $newInstance); } } else { $object = $this->invokeClass($abstract, $vars); } if (!$newInstance) { $this->instances[$abstract] = $object; } return $object; }
這是第二次執(zhí)行流程
public function make($abstract, $vars = [], $newInstance = false) { // 判斷$vars這個(gè)變量是否為true if (true === $vars) { // 總是創(chuàng)建新的實(shí)例化對象 $newInstance = true; $vars = []; } // app 這里就是在容器別名里獲取傳遞過來的app 如果沒有則就是app // 第二次執(zhí)行時(shí) $abstract = think\App $abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract; // 從容器實(shí)例中獲取 如果存在則直接返回對應(yīng)的實(shí)例 也就是使用注冊樹模式 if (isset($this->instances[$abstract]) && !$newInstance) { return $this->instances[$abstract]; } // think\App 從容器標(biāo)識中獲取 // 第二次執(zhí)行$this->bind['think\App']不存在走else if (isset($this->bind[$abstract])) { // 將think\App 復(fù)制給$concrete變量 $concrete = $this->bind[$abstract]; // 用于代表匿名函數(shù)的類 判斷是不是閉包 if ($concrete instanceof Closure) { $object = $this->invokeFunction($concrete, $vars); } else { // $this->name['app'] = think\App $this->name[$abstract] = $concrete; // 在執(zhí)行一次本類的make方法,也就是本方法 // think\App return $this->make($concrete, $vars, $newInstance); } } else { // think\App $object = $this->invokeClass($abstract, $vars); } if (!$newInstance) { // 把創(chuàng)建的容器存起來 //$this->instances['think\App'] = $object; $this->instances[$abstract] = $object; } return $object; }
public function invokeClass($class, $vars = []) { try { /** * ReflectionClass Object ( [name] => think\App ) */ // 這里就是之前文章提到的反射 $reflect = new ReflectionClass($class); if ($reflect->hasMethod('__make')) { $method = new ReflectionMethod($class, '__make'); if ($method->isPublic() && $method->isStatic()) { $args = $this->bindParams($method, $vars); return $method->invokeArgs(null, $args); } } // 通過反射獲取think\App的構(gòu)造函數(shù) $constructor = $reflect->getConstructor(); $args = $constructor ? $this->bindParams($constructor, $vars) : []; // 從給出的參數(shù)創(chuàng)建一個(gè)新的類實(shí)例 return $reflect->newInstanceArgs($args); } catch (ReflectionException $e) { throw new ClassNotFoundException('class not exists: ' . $class, $class); } }
執(zhí)行流程圖
既然把代碼都理清楚了,這時(shí)來理一下執(zhí)行的流程圖可以看的更清晰。
以上是“ThinkPHP容器之容器是如何返回實(shí)例的”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)頁名稱:ThinkPHP容器之容器是如何返回實(shí)例的
文章分享:http://muchs.cn/article4/igspie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司、標(biāo)簽優(yōu)化、自適應(yīng)網(wǎng)站、微信公眾號、全網(wǎng)營銷推廣、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)