Yii 2.0最顯著的特徵之一就是引入了命名空間,所以對於自定義類的引入方式也同以前有所不一樣。這篇文章討論一下如何利用Yii 2.0的自動加載機制,向系統中引入自定義類和命名空間。本文旨在拋磚引玉,若是有理解不當敬請指正,歡迎你們把本身的方法拿出來分享。
咱們但願被引入的類應該達成一下兩點:php
咱們使用Yii 2.0基礎模板做爲演示環境,項目根目錄命名爲basic
(後文中會寫成/
),這是根目錄結構: web
basic ├── assets ├── commands ├── config ├── controllers ├── mail ├── models ├── runtime ├── tests ├── vendor ├── views └── web
創建目錄 /libs
並創建文件Freedom.php。數組
<?php class Freedom { public static function yell() { echo "I am FREE!"; } }
Yii::$classMap
添加映射打開配置文件/config/web.php
,在文件頭部向[[Yii::$classMap]]
屬性添加類映射。app
<?php ... Yii::$classMap['Freedom'] = '@app/libs/Freedom.php'; ... $config = [ ... ]; return $config;
注意: 不要對[[Yii::$classMap]]
使用=
直接賦值,由於該屬性中定義了Yii的一些核心類映射,直接賦值會致使這些映射丟失而Yii autoloader加載不到核心類。No zuo no die don't try.dom
見證奇蹟的時刻。在系統中嘗試調用這個類,咱們使用SiteController::actionIndex()爲例。yii
<?php ... use Freedom; // 別忘了導入這個類,或者在後面調用的時候使用"\Freedom"。 class SiteController extends Controller ... public function actionIndex() { Freedom::yell(); } }
好了,刷新一下試試。ui
那如今咱們來須要介紹一下[[Yii::$classMap]]
到底是個毛。這貨其實是一個關聯數組,數組鍵爲「去掉前導反斜線的徹底權限定類名」,對應值爲定義了該類的文件路徑,其中文件路徑支持路徑別名。在代碼中調用到還沒有加載的類時,Yii的audoloader會掃描這個屬性以得到須要加載的類文件名。spa
因此,咱們把剛剛定義的類加入到這個映射數組中,它就能夠被Yii延遲加載了。事實上咱們能夠在任何位置添加這個映射,只要在目標類被調用以前就能夠。應用的主配置文件是一個比較理想的位置,由於配置文件加載在Yii.php以後,能夠在其中訪問到Yii
類(有興趣的同窗能夠去看一下入口腳本),並且配置數據能夠集中在一個文件裏。code
另外,因爲咱們定義的類在根命名空間下,因此「去掉前導反斜線的徹底權限定類名」就只剩下Freedom
了。若是你的類使用了命名空間,只須要在數組鍵裏寫上徹底限定名稱就好了(e.g. ['custom\classes\Freedom'])。資源
有時候咱們須要寫一組相互關聯的類,若是這些類存在依賴關係的話像上面這樣給每一個類配置映射會……非(jue)常(b)不(gao)體(si)面(ren)。若是你定義命名空間下的類時遵循 PSR-4 標準,咱們能夠一次引入整個命名空間。
此次咱們要使用的屬性是[[\yii\base\Application::$aliases]]
。它也是一個關聯數組,將一個路徑別名映射到一個目錄或者另外一個已經存在的路徑別名。其中數組鍵是要指定的別名,對應值是目標路徑。
咱們只須要在創建一個命名空間別名,把它映射到保存這個命名空間下全部類的根目錄,就能夠了。固然這個根目錄如下的文件結構和類定義要遵循PSR-4,否則autoloader是找不到對應文件的。
試一下:
咱們決定在/libs/vendors
目錄下定義一組以命名空間組織的類,其根目錄命名爲free-classes
,這組類的所有在命名空間free_classes
下。注意這裏我故意使根目錄名與根命名空間名不一致以表示映射根目錄不必定要和命名空間同名。
建立文件/libs/vendors/free-classes/persons/Slave.php
,沒有目錄請自行建立。
<?php namespace free_classes\persons; class Slave { public static function isFree() { var_dump("I'm FREE now, thank you!"); } }
建立文件/libs/vendors/free-classes/vehicles/cars/Porsche.php
。
<?php namespace free_classes\vehicles\cars; class Porsche { public static function isFree() { var_dump('Are you kidding?!'); } }
注意: free-classes
如下的目錄名和結構都要遵循PSR-4標準。
[[\yii\web\Application::$aliases]]
這裏要說一下,若是咱們的命名空間爲namespace\subnamespace
,那麼咱們應該設置的路徑別名就是@namespace/subnamespace
(詳解參照 PSR-4 )。
打開配置文件/config/web.php
,配置Application的aliaes屬性:
<?php Yii::$classMap['Freedom'] = '@app/libs/Freedom.php'; ... $config = [ 'id' => 'basic', ... 'aliases' => [ '@free_classes' => '@app/libs/vendors/free-classes' ], ... ]; return $config;
又要見證奇蹟了,仍是選在SiteController::actionIndex()裏。
<?php ... use free_classes\persons\Slave; // 仍是別忘了導入 use free_classes\vehicles\cars\Porsche; class SiteController extends Controller ... public function actionIndex() { // Freedom::yell(); Slave::isFree(); Porsche::isFree(); } }
刷新一下;-)