国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Yii2的深入學習--自動加載機制

2019-11-14 14:43:24
字體:
來源:轉載
供稿:網友

Yii2 的自動加載分兩部分,一部分是 Composer 的自動加載機制,另一部分是 Yii2 框架自身的自動加載機制。

Composer自動加載

對于庫的自動加載信息,Composer 生成了一個 vendor/autoload.php 文件。你可以簡單的引入這個文件,你會得到一個自動加載的支持。

在之前的文章,入口文件的介紹中,我們可以看到如下內容:

// 引入 vendor 中的 autoload.php 文件,會基于 composer 的機制自動加載類require(__DIR__ . '/../vendor/autoload.php');

因為這個系列主要是關于 Yii2 的,所以有關 Composer 自動加載機制就不在這里詳細說明了。

可查閱資料:

  1. Composer 自動加載
  2. Composer 自動加載-參考
  3. Composer 中文官網

Yii2 框架的自動加載機制

Yii2 框架的自動加載是通過 spl_autoload_register 方法實現的。

在之前的文章,入口文件的介紹中,我們可以看到如下內容:

// 引入 Yii 框架的文件 Yii.phprequire(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');

Yii.php 里究竟是什么內容?如何實現了自動加載?

下面我們來看一下,Yii.php 的內容如下:

<?php/** * Yii bootstrap file. * * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */require(__DIR__ . '/BaseYii.php');/** * Yii is a helper class serving common framework functionalities. * * It extends from [[/yii/BaseYii]] which PRovides the actual implementation. * By writing your own Yii class, you can customize some functionalities of [[/yii/BaseYii]]. * * @author Qiang Xue <qiang.xue@Gmail.com> * @since 2.0 */class Yii extends /yii/BaseYii{}/** * spl_autoload_register — 注冊給定的函數作為 __autoload 的實現 * * bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] ) * * 將函數注冊到SPL __autoload函數隊列中。如果該隊列中的函數尚未激活,則激活它們。 * 如果在你的程序中已經實現了__autoload()函數,它必須顯式注冊到__autoload()隊列中。 * 因為 spl_autoload_register()函數會將Zend Engine中的__autoload()函數取代為spl_autoload()或spl_autoload_call()。 * 如果需要多條 autoload 函數,spl_autoload_register() 滿足了此類需求。 * 它實際上創建了 autoload 函數的隊列,按定義時的順序逐個執行。 * 相比之下, __autoload() 只可以定義一次。 * * autoload_function * 欲注冊的自動裝載函數。如果沒有提供任何參數,則自動注冊 autoload 的默認實現函數spl_autoload()。 * * throw * 此參數設置了 autoload_function 無法成功注冊時, spl_autoload_register()是否拋出異常。 * * prepend * 如果是 true,spl_autoload_register() 會添加函數到隊列之首,而不是隊列尾部。 * * Yii 注冊了 Yii 的 autoload 函數,實現自動加載, 其實現在 /yii/BaseYii 中 */spl_autoload_register(['Yii', 'autoload'], true, true);// 定義 Yii 核心的 class 的類名與文件地址的 MapYii::$classMap = require(__DIR__ . '/classes.php');// 創建 Yii 的依賴注入的容器Yii::$container = new yii/di/Container();

其主要內容就是引入了 BaseYii.php 文件,然后聲明了類 Yii,繼承了 BaseYii,然后注冊了 Yii (其實是 BaseYii)的 autoload 方法,去實現自動加載。之后又引入了Yii 核心類名與文件地址一一對應的 Map,存儲到 Yii::$classMap 中。最后創建了一個 yii/di/Container 的實例,存儲到 Yii::$container 中。

可以看出實現自動加載的關鍵代碼是:

spl_autoload_register(['Yii', 'autoload'], true, true);

下面我們來看一下 BaseYii 中 autoload 方法的實現,其內容如下:

    /**     * Class autoload loader.     * This method is invoked automatically when PHP sees an unknown class.     * The method will attempt to include the class file according to the following procedure:     *     * 1. Search in [[classMap]];     * 2. If the class is namespaced (e.g. `yii/base/Component`), it will attempt     *    to include the file associated with the corresponding path alias     *    (e.g. `@yii/base/Component.php`);     *     * This autoloader allows loading classes that follow the [PSR-4 standard](http://www.php-fig.org/psr/psr-4/)     * and have its top-level namespace or sub-namespaces defined as path aliases.     *     * Example: When aliases `@yii` and `@yii/bootstrap` are defined, classes in the `yii/bootstrap` namespace     * will be loaded using the `@yii/bootstrap` alias which points to the directory where bootstrap extension     * files are installed and all classes from other `yii` namespaces will be loaded from the yii framework directory.     *     * Also the [guide section on autoloading](guide:concept-autoloading).     *     * @param string $className the fully qualified class name without a leading backslash "/"     * @throws UnknownClassException if the class does not exist in the class file     */    public static function autoload($className)    {        // 自動加載類        if (isset(static::$classMap[$className])) {            // 如果 $classMap 中存在該類,就直接使用            $classFile = static::$classMap[$className];            // 如果第一個字符串為'@',就意味著對應的文件地址是別名,就將它轉化成真實的文件地址            if ($classFile[0] === '@') {                $classFile = static::getAlias($classFile);            }        } elseif (strpos($className, '//') !== false) {            // 如果存在'//',就意味著含有 namespace,可以拼成別名,再根據別名獲取真實的文件地址            $classFile = static::getAlias('@' . str_replace('//', '/', $className) . '.php', false);            // 沒取到真是文件地址或者獲取的地址不是一個文件,就返回空            if ($classFile === false || !is_file($classFile)) {                return;            }        } else {            return;        }        // 引入該類的文件        include($classFile);        // 如果是調試模式,而且 $className 即不是類,不是接口,也不是 trait,就拋出異常        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?");        }    }

其中,大家可能不太清楚 getAlias 方法,這個方法其實就是將 Yii2 中的別名轉化成真實的文件地址,關于該方法的具體內容,之后會詳細講解。

舉幾個例子,幫助大家理解一下。

如果 Yii::$classMap 的值如下:

Yii::$classMap = [    'app/test/Test' => '/var/www/basic/webtest/Test.php'];

當你使用 ‘app/test/Test’ 類時,就會自動引入 '/var/www/basic/webtest/Test.php' 文件,項目中的內容當然不是這個樣子的,這只是個簡單的例子,便于大家理解。

在繼續上面的例子,如果你使用了‘yii/base/Component’ 類,它就會轉變成 ‘@yii/base/Component.php’ 別名,然后在根據別名獲取到它的文件地址,引入進來。

以上就是 Yii2 的自動加載機制的基本內容~~

 

對 Yii2 源碼有興趣的同學可以關注項目 yii2-2.0.3-annotated,現在在上面已經添加了不少關于 Yii2 源碼的注釋,之后還會繼續添加~

有興趣的同學也可以參與進來,提交 Yii2 源碼的注釋。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金秀| 沅陵县| 安图县| 米林县| 霍城县| 江油市| 罗平县| 黄浦区| 德化县| 湘乡市| 凤山县| 洞口县| 团风县| 临汾市| 佛坪县| 延津县| 沁源县| 佛山市| 马龙县| 佛教| 赣州市| 阿拉尔市| 兰考县| 沈阳市| 新疆| 光泽县| 井冈山市| 安丘市| 阿合奇县| 区。| 定陶县| 都江堰市| 七台河市| 普安县| 微博| 扎囊县| 长治市| 宁城县| 大关县| 尤溪县| 宾阳县|