<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                在Yii中,所有類、接口、Traits都可以使用類的自動加載機制實現在調用前自動加載。Yii借助了PHP的類自動加載機制高效實現了類的定位、導入,這一機制兼容?[PSR-4](http://www.php-fig.org/psr/psr-4/)?的標準。在Yii中,類僅在調用時才會被加載,特別是核心類,其定位非常快,這也是Yii高效高性能的一個重要體現。 ## 自動加載機制的實現[](http://www.digpage.com/autoload.html#id1 "Permalink to this headline") Yii的類自動加載,依賴于PHP的?spl_autoload_register()?, 注冊一個自己的自動加載函數(autoloader),并插入到自動加載函數棧的最前面,確保Yii的autoloader會被最先調用。 類自動加載的這個機制的引入要從入口文件?index.php?開始說起: ~~~ <?php defined('YII_DEBUG') or define('YII_DEBUG', false); defined('YII_ENV') or define('YII_ENV', 'prod'); // 這個是第三方的autoloader require(__DIR__ . '/../../vendor/autoload.php'); // 這個是Yii的Autoloader,放在最后面,確保其插入的autoloader會放在最前面 require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php'); // 后面不應再有autoloader了 require(__DIR__ . '/../../common/config/aliases.php'); $config = yii\helpers\ArrayHelper::merge( require(__DIR__ . '/../../common/config/main.php'), require(__DIR__ . '/../../common/config/main-local.php'), require(__DIR__ . '/../config/main.php'), require(__DIR__ . '/../config/main-local.php') ); $application = new yii\web\Application($config); $application->run(); ~~~ 這個文件主要看點在于第三方autoloader與Yii 實現的autoloader的順序。不管第三方的代碼是如何使用?spl_autoload_register()?來注冊自己的autoloader的,只要Yii 的代碼在最后面,就可以確保其可以將自己的autoloader插入到整個autoloder 棧的最前面,從而在需要時最先被調用。 接下來,看看Yii是如何調用?spl_autoload_register()?注冊autoloader的, 這要看?Yii.php?里發生了些什么: ~~~ <?php require(__DIR__ . '/BaseYii.php'); class Yii extends \yii\BaseYii { } // 重點看這個 spl_autoload_register spl_autoload_register(['Yii', 'autoload'], true, true); // 下面的語句讀取了一個映射表 Yii::$classMap = include(__DIR__ . '/classes.php'); Yii::$container = new yii\di\Container; ~~~ 這段代碼,調用了?spl_autoload_register(['Yii',?'autoload',?true,?true])?,將?Yii::autoload()?作為autoloader插入到棧的最前面了。并將?classes.php?讀取到?Yii::$classMap?中,保存了一個映射表。 在上面的代碼中,Yii類是里面沒有任何代碼,并未對?BaseYii::autoload()?進行重載,所以,這個spl_autoload_register()?實際上將?BaseYii::autoload()?注冊為autoloader。如果,你要實現自己的autoloader,可以在 Yii 類的代碼中,對?autoload()?進行重載。 在調用?spl_autoload_register()?進行autoloader注冊之后,Yii將?calsses.php?這個文件作為一個映射表保存到?Yii::$classMap?當中。這個映射表,保存了一系列的類名與其所在PHP文件的映射關系,比如: ~~~ return [ 'yii\base\Action' => YII2_PATH . '/base/Action.php', 'yii\base\ActionEvent' => YII2_PATH . '/base/ActionEvent.php', ... ... 'yii\widgets\PjaxAsset' => YII2_PATH . '/widgets/PjaxAsset.php', 'yii\widgets\Spaceless' => YII2_PATH . '/widgets/Spaceless.php', ]; ~~~ 這個映射表以類名為鍵,以實際類文件為值,Yii所有的核心類都已經寫入到這個?classes.php?文件中,所以,核心類的加載是最便捷,最快的。現在,來看看這個關鍵先生?BaseYii::autoload() ~~~ public static function autoload($className) { if (isset(static::$classMap[$className])) { $classFile = static::$classMap[$className]; if ($classFile[0] === '@') { $classFile = static::getAlias($classFile); } } elseif (strpos($className, '\\') !== false) { $classFile = static::getAlias('@' . str_replace('\\', '/', $className) . '.php', false); if ($classFile === false || !is_file($classFile)) { return; } } else { return; } include($classFile); if (YII_DEBUG && !class_exists($className, false) && !interface_exists($className, false) && !trait_exists($className, false)) { throw new UnknownClassException( "Unable to find '$className' in file: $classFile. Namespace missing?"); } } ~~~ 從這段代碼來看Yii類自動加載機制的運作原理: * 檢查?$classMap[$className]?看看是否在映射表中已經有擬加載類的位置信息; * 如果有,再看看這個位置信息是不是一個路徑別名,即是不是以?@?打頭, 是的話,將路徑別名解析成實際路徑。 如果映射表中的位置信息并非一個路徑別名,那么將這個路徑作為類文件的所在位置。 類文件的完整路徑保存在?$classFile?; * 如果?$classMap[$className]?沒有該類的信息, 那么,看看這個類名中是否含有?\?, 如果沒有,說明這是一個不符合規范要求的類名,autoloader直接返回。 PHP會嘗試使用其他已經注冊的autoloader進行加載。 如果有?\?,認為這個類名符合規范,將其轉換成路徑形式。 即所有的\?用?/?替換,并加上?.php?的后綴。 * 將替換后的類名,加上?@?前綴,作為一個路徑別名,進行解析。 從別名的解析過程我們知道,如果根別名不存在,將會拋出異常。 所以,類的命名,必須以有效的根別名打頭: ~~~ // 有效的類名,因為@yii是一個已經預定義好的別名 use yii\base\Application; // 無效的類名,因為沒有 @foo 或 @foo/bar 的根別名,要提前定義好 use foo\bar\SomeClass; ~~~ * 使用PHP的?include()?將類文件加載進來,實現類的加載。 從其運作原理看,最快找到類的方式是使用映射表。 其次,Yii中所有的類名,除了符合規范外,還需要提前注冊有效的根別名。 ## 運用自動加載機制[](http://www.digpage.com/autoload.html#id2 "Permalink to this headline") 在入口腳本中,除了Yii自己的autoloader,還有一個第三方的autoloader: ~~~ require(__DIR__ . '/../../vendor/autoload.php'); ~~~ 這個其實是Composer提供的autoloader。Yii使用Composer來作為包依賴管理器,因此,建議保留Composer的autoloader,盡管Yii的autoloader也能自動加載使用Composer安裝的第三方庫、擴展等,而且更為高效。但考慮到畢竟是人家安裝的,人家還有一套自己專門的規則,從維護性、兼容性、擴展性來考慮,建議保留Composer的autoloader。 如果還有其他的autoloader,一定要在Yii的autoloader注冊之前完成注冊,以保證Yii的autoloader總是最先被調用。 如果你有自己的autoloader,也可以不安裝Yii的autoloaer,只是這樣未必能有Yii的高效,且還需要遵循一套類似的類命名和加載的規則。就個人的經驗而言,Yii的autoloader完全夠用,沒必要自己重復造輪子。 至于Composer如何自動加載類文件,這里就不過多的占用篇幅了。可以看看?[Composer的文檔](https://getcomposer.org/doc/04-schema.md#autoload)?。 如果覺得《深入理解Yii2.0》對您有所幫助,也請[幫助《深入理解Yii2.0》](http://www.digpage.com/donate.html#donate)。 謝謝!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看