在yii中,所有類、介面、traits都可以使用類的自動載入機制實現在呼叫前自動載入。yii借助了php的類自動載入機制高效實現了類的定位、匯入,這一機制相容 psr-4 的標準。在yii中,類僅在呼叫時才會被載入,特別是核心類,其定位非常快,這也是yii高效高效能的乙個重要體現。
yii的類自動載入,依賴於php的 spl_autoload_register()
, 註冊乙個自己的自動載入函式(autoloader),並插入到自動載入函式棧的最前面,確保yii的autoloader會被最先呼叫。
類自動載入的這個機制的引入要從入口檔案 index.php
開始說起:
12 34 5
6 78 9
1011
1213
1415
1617
1819
2021
22
<?phpdefined
('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'));
=new
($config
);->
run();
這個檔案主要看點在於第三方autoloader與yii 實現的autoloader的順序。不管第三方的**是如何使用 spl_autoload_register()
來註冊自己的autoloader的,只要yii 的**在最後面,就可以確保其可以將自己的autoloader插入到整個autoloder 棧的最前面,從而在需要時最先被呼叫。
接下來,看看yii是如何呼叫 spl_autoload_register()
註冊autoloader的, 這要看 yii.php
裡發生了些什麼:
12 34 5
6 78 9
1011
1213
<?phprequire
(__dir__
.'/baseyii.php'
);class
yiiextends
\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檔案的對映關係,比如:
1234567
89
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()
12 34 5
6 78 9
1011
1213
1415
1617
1819
2021
2223
2425
26
publicstatic
function
autoload
($classname)}
elseif
(strpos
($classname
,'\\'
)!==
false)}
else
include
($classfile
);if
(yii_debug&&!
class_exists
($classname
,false)&&
!inte***ce_exists
($classname
,false)&&
!trait_exists
($classname
,false
))}
從這段**來看yii類自動載入機制的運作原理:
從其運作原理看,最快找到類的方式是使用對映表。 其次,yii中所有的類名,除了符合規範外,還需要提前註冊有效的根別名。
在入口指令碼中,除了yii自己的autoloader,還有乙個第三方的autoloader:
require(__dir__
.'/../../vendor/autoload.php'
);
這個其實是composer提供的autoloader。yii使用composer來作為包依賴管理器,因此,建議保留composer的autoloader,儘管yii的autoloader也能自動載入使用composer安裝的第三方庫、擴充套件等,而且更為高效。但考慮到畢竟是人家安裝的,人家還有一套自己專門的規則,從維護性、相容性、擴充套件性來考慮,建議保留composer的autoloader。
如果還有其他的autoloader,一定要在yii的autoloader註冊之前完成註冊,以保證yii的autoloader總是最先被呼叫。
yii2的自動載入類檔案
一。檢視了一下yii2的載入原理 每個命名空間都有對應的路徑 然後檔名一定要與類名相同 通過yii classmap可設定。或別名也可識別。當我要用乙個不認識的類名時,會自動呼叫魔術方法yii類下的spl autoload register,然後執行autoload方法,在這個方法裡會把對應的類檔案...
Yii原始碼解讀 類自動載入
yii的類自動載入,依賴於php的spl autoload register 註冊乙個自己的自動載入函式 autoloader 並插入到自動載入函式棧的最前面,確保yii的autoloader會被最先呼叫。require dir vendor autoload.php require dir ven...
yii2框架 yii2自身的自動載入 三
上一節說完了composer的自動載入,下面我們來說一下yii2自身的自動載入。在我們的入口檔案,例如index.php,如下 comment out the following two lines when deployed to production defined yii debug or d...