麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 語(yǔ)言 > PHP > 正文

thinkphp5.1框架中容器(Container)和門(mén)面(Facade)的實(shí)現(xiàn)方法分析

2024-05-05 00:10:45
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

本文實(shí)例講述了thinkphp5.1框架中容器(Container)和門(mén)面(Facade)的實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:

tp5.1中引入了容器(Container)和門(mén)面(Facade)這兩個(gè)新的類

官方文檔已經(jīng)給出了定義:

容器(Container)實(shí)現(xiàn)類的統(tǒng)一管理,確保對(duì)象實(shí)例的唯一性。

門(mén)面(Facade)為容器(Container)中的類提供了一個(gè)靜態(tài)調(diào)用接口,相比于傳統(tǒng)的靜態(tài)方法調(diào)用, 帶來(lái)了更好的可測(cè)試性和擴(kuò)展性,你可以為任何的非靜態(tài)類庫(kù)定義一個(gè)facade類。

深入源碼,我們來(lái)看看它到底是如何實(shí)現(xiàn)的:

// 在框架目錄下的base.php文件// 注冊(cè)核心類到容器Container::getInstance()->bind([  'app'          => App::class,  'build'         => Build::class,  'cache'         => Cache::class,  'config'        => Config::class,  ...]);// 注冊(cè)核心類的靜態(tài)代理Facade::bind([  facade/App::class   => App::class,  facade/Build::class  => Build::class,  facade/Cache::class  => Cache::class,  facade/Config::class  => Config::class,  ...]);// 注冊(cè)類庫(kù)別名Loader::addClassAlias([  'App'   => facade/App::class,  'Build'  => facade/Build::class,  'Cache'  => facade/Cache::class,  'Config'  => facade/Config::class,  ...]);

容器實(shí)現(xiàn):

這里,框架已經(jīng)幫我們綁定了系統(tǒng)常用類到容器中,在之后使用時(shí),只需要調(diào)用助手函數(shù) app()進(jìn)行容器中的類解析調(diào)用,對(duì)于已經(jīng)綁定的類標(biāo)識(shí),會(huì)自動(dòng)快速實(shí)例化。

// 實(shí)例化緩存類app('cache');// app('cache', ['file']); 參數(shù)化調(diào)用// 相當(dāng)于執(zhí)行了Container::get('cache');// 查看源碼,Container調(diào)用的其實(shí)是make方法,在該方法里調(diào)用反射等實(shí)現(xiàn)類的實(shí)例化,過(guò)程如下:public function make($abstract, $vars = [], $newInstance = false){  if (true === $vars) {    // 總是創(chuàng)建新的實(shí)例化對(duì)象    $newInstance = true;    $vars    = [];  }  if (isset($this->instances[$abstract]) && !$newInstance) {    $object = $this->instances[$abstract];  } else {    if (isset($this->bind[$abstract])) {      $concrete = $this->bind[$abstract];       // 閉包實(shí)現(xiàn)      if ($concrete instanceof /Closure) {        $object = $this->invokeFunction($concrete, $vars);      } else {        $object = $this->make($concrete, $vars, $newInstance);      }    } else {       // 反射實(shí)現(xiàn)      $object = $this->invokeClass($abstract, $vars);    }    if (!$newInstance) {      $this->instances[$abstract] = $object;    }  }  return $object;}/** * 調(diào)用反射執(zhí)行類的實(shí)例化 支持依賴注入 * @access public * @param string  $class 類名 * @param array   $vars 變量 * @return mixed */public function invokeClass($class, $vars = []){  $reflect   = new /ReflectionClass($class);  $constructor = $reflect->getConstructor();  if ($constructor) {    $args = $this->bindParams($constructor, $vars);  } else {    $args = [];  }  return $reflect->newInstanceArgs($args);}/** * 執(zhí)行函數(shù)或者閉包方法 支持參數(shù)調(diào)用 * @access public * @param string|array|/Closure $function 函數(shù)或者閉包 * @param array         $vars   變量 * @return mixed */public function invokeFunction($function, $vars = []){  $reflect = new /ReflectionFunction($function);  $args  = $this->bindParams($reflect, $vars);  return $reflect->invokeArgs($args);}

簡(jiǎn)而言之,容器內(nèi)部是通過(guò)反射類或閉包等來(lái)實(shí)現(xiàn)類的實(shí)例化。

門(mén)面實(shí)現(xiàn):

以一個(gè)例子來(lái)分析:

facade/Config::get('app_debug');

我們來(lái)分析一下它的實(shí)現(xiàn)方式:

// thinkphp/library/facade/Config 類namespace think/facade;use think/Facade;class Config extends Facade{}// 從源代碼上看 Config本身沒(méi)有任何方法,它繼承了Facade的方法,但Facade并沒(méi)有g(shù)et這個(gè)靜態(tài)方法// 此時(shí),系統(tǒng)自動(dòng)觸發(fā)了魔術(shù)方法:__callStatic(),Facade重寫(xiě)了此方法:public static function __callStatic($method, $params){  return call_user_func_array([static::createFacade(), $method], $params);}// 可見(jiàn),最后調(diào)用的是用戶自定義函數(shù):call_user_func_array([實(shí)例, 方法], 參數(shù)),為了獲得Config實(shí)例,F(xiàn)acade又定義了一個(gè)獲取對(duì)象的方法:/** * 創(chuàng)建Facade實(shí)例 * @static * @access protected * @param string  $class     類名或標(biāo)識(shí) * @param array   $args      變量 * @param bool   $newInstance  是否每次創(chuàng)建新的實(shí)例 * @return object */protected static function createFacade($class = '', $args = [], $newInstance = false){  $class    = $class ?: static::class;  $facadeClass = static::getFacadeClass();  if ($facadeClass) {    $class = $facadeClass;  } elseif (isset(self::$bind[$class])) {    $class = self::$bind[$class];  }  if (static::$alwaysNewInstance) {    $newInstance = true;  }  return Container::getInstance()->make($class, $args, $newInstance);}// 其內(nèi)部是通過(guò)容器來(lái)實(shí)例化對(duì)象// 因?yàn)樵赽ase.php中已經(jīng)將 think/Config 類綁定到 config 這個(gè)標(biāo)識(shí)Container::getInstance()->bind([  'config' => Config::class])// 在 createFacade 方法中,獲取類的名稱:$class = $class ?: static::class; 即得到 config 這個(gè)標(biāo)識(shí)// 在容器的make方法中,根據(jù)config標(biāo)識(shí),找到綁定的 think/Config 類,并調(diào)用其動(dòng)態(tài)方法 get。facade/Config::get('app_debug');// 最后調(diào)用的是:(new think/Config())->get('app_debug');

簡(jiǎn)而言之,門(mén)面的實(shí)現(xiàn)是通過(guò)PHP的魔術(shù)方法 __callStatic,再配合容器來(lái)實(shí)現(xiàn)動(dòng)態(tài)類的靜態(tài)化調(diào)用。

希望本文所述對(duì)大家基于ThinkPHP框架的PHP程序設(shè)計(jì)有所幫助。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到PHP教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 91精选视频 | 91女上位 在线播放 性欧美日本 | 自拍偷拍999 | 国产精品视频二区不卡 | 久久久久久久高清 | 国产伦乱视频 | av成人免费在线观看 | 制服丝袜成人动漫 | 黄色大片在线免费观看 | 久久久久中精品中文字幕19 | 黄色电影免费提供 | 精品国产一区二区三 | 成年人在线视频 | 激情网站免费观看 | 又黄又爽免费无遮挡在线观看 | 国产精品色在线网站 | 草草久| 色无极影院亚洲 | 亚洲综合91 | 成人一级免费视频 | 一级国产电影 | 一区二区三区日韩 | 久久久一区二区三区精品 | 久久久麻豆| 欧美国产一区二区三区激情无套 | 欧美视频在线观看一区 | 国产羞羞网站 | 久久国产精品二国产精品中国洋人 | 日韩av电影免费看 | 欧美性黄 | 日本精品免费观看 | 妇女毛片| 99成人精品视频 | 黄色影院在线看 | 国产在线精品一区二区三区 | h视频免费看 | 久久最新免费视频 | 国产好片无限资源 | 狠狠干五月| 欧美性猛交xxxxx按摩国内 | 国产精品美女久久久久久网站 |