php定义一个名为Vehicles,[PHP][Yii2.0] 以Yii 2.0风格加载自定义类或命名空间 [配置使用Yii2 autoloader]...
Yii 2.0最顯著的特征之一就是引入了命名空間,因此對于自定義類的引入方式也同之前有所不同。這篇文章討論一下如何利用Yii 2.0的自動加載機制,向系統中引入自定義類和命名空間。本文旨在拋磚引玉,如果有理解不當敬請指正,歡迎大家把自己的方法拿出來分享。
我們希望被引入的類應該達成一下兩點:
在應用中的任這里輸入代碼意位置可以使用該類名或命名空間,而不用顯式調用require()/include()。
利用Yii的autoloader,僅在類被調用時加載,以遵循Yii按需加載的原則,節省資源。
我們使用Yii 2.0基礎模板作為演示環境,項目根目錄命名為basic(后文中會寫成/),這是根目錄結構:
basic
├── assets
├── commands
├── config
├── controllers
├── models
├── runtime
├── tests
├── vendor
├── views
└── web
加載自定義類
I. 定義類文件
建立目錄 /libs 并建立文件Freedom.php。
class Freedom
{
public static function yell()
{
echo "I am FREE!";
}
}
II. 向Yii::$classMap添加映射
打開配置文件/config/web.php,在文件頭部向[[Yii::$classMap]]屬性添加類映射。
...
Yii::$classMap['Freedom'] = '@app/libs/Freedom.php';
...
$config = [
...
];
return $config;
注意: 不要對[[Yii::$classMap]]使用=直接賦值,因為該屬性中定義了Yii的一些核心類映射,直接賦值會導致這些映射丟失而Yii autoloader加載不到核心類。No zuo no die don't try.
III. 使用自定義類
見證奇跡的時刻。在系統中嘗試調用這個類,我們使用SiteController::actionIndex()為例。
...
use Freedom; // 別忘了導入這個類,或者在后面調用的時候使用"\Freedom"。
class SiteController extends Controller
...
public function actionIndex()
{
Freedom::yell();
}
}
好了,刷新一下試試。
IV. 如果你還關心為什么
那現在我們來需要介紹一下[[Yii::$classMap]]究竟是個毛。這貨實際上是一個關聯數組,數組鍵為“去掉前導反斜線的完全權限定類名”,對應值為定義了該類的文件路徑,其中文件路徑支持路徑別名。在代碼中調用到尚未加載的類時,Yii的audoloader會掃描這個屬性以獲得需要加載的類文件名。
所以,我們把剛剛定義的類加入到這個映射數組中,它就可以被Yii延遲加載了。事實上我們可以在任何位置添加這個映射,只要在目標類被調用之前就可以。應用的主配置文件是一個比較理想的位置,因為配置文件加載在Yii.php之后,可以在其中訪問到Yii類(有興趣的同學可以去看一下入口腳本),而且配置數據可以集中在一個文件里。
另外,由于我們定義的類在根命名空間下,所以“去掉前導反斜線的完全權限定類名”就只剩下Freedom了。如果你的類使用了命名空間,只需要在數組鍵里寫上完全限定名稱就行了(e.g. ['custom\classes\Freedom'])。
加載整個命名空間
有時候我們需要寫一組相互關聯的類,如果這些類存在依賴關系的話像上面這樣給每個類配置映射會……非(jue)常(b)不(gao)體(si)面(ren)。如果你定義命名空間下的類時遵循 PSR-4 標準,我們可以一次引入整個命名空間。
這次我們要使用的屬性是[[\yii\base\Application::$aliases]]。它也是一個關聯數組,將一個路徑別名映射到一個目錄或者另一個已經存在的路徑別名。其中數組鍵是要指定的別名,對應值是目標路徑。
我們只需要在建立一個命名空間別名,把它映射到保存這個命名空間下所有類的根目錄,就可以了。當然這個根目錄以下的文件結構和類定義要遵循PSR-4,不然autoloader是找不到對應文件的。
試一下:
I. 定義命名空間和類文件
我們決定在/libs/vendors目錄下定義一組以命名空間組織的類,其根目錄命名為free-classes,這組類的全部在命名空間free_classes下。注意這里我故意使根目錄名與根命名空間名不一致以表示映射根目錄不一定要和命名空間同名。
創建文件/libs/vendors/free-classes/persons/Slave.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。
namespace free_classes\vehicles\cars;
class Porsche
{
public static function isFree()
{
var_dump('Are you kidding?!');
}
}
注意: free-classes以下的目錄名和結構都要遵循PSR-4標準。
II. 配置[[\yii\web\Application::$aliases]]
這里要說一下,如果我們的命名空間為namespace\subnamespace,那么我們應該設置的路徑別名就是@namespace/subnamespace(詳解參照 PSR-4 )。
打開配置文件/config/web.php,配置Application的aliaes屬性:
Yii::$classMap['Freedom'] = '@app/libs/Freedom.php';
...
$config = [
'id' => 'basic',
...
'aliases' => [
'@free_classes' => '@app/libs/vendors/free-classes'
],
...
];
return $config;
III. 使用命名空間下的類
又要見證奇跡了,還是選在SiteController::actionIndex()里。
...
use free_classes\persons\Slave; // 還是別忘了導入
use free_classes\vehicles\cars\Porsche;
class SiteController extends Controller
...
public function actionIndex()
{
// Freedom::yell();
Slave::isFree();
Porsche::isFree();
}
}
刷新一下;-)
總結
以上是生活随笔為你收集整理的php定义一个名为Vehicles,[PHP][Yii2.0] 以Yii 2.0风格加载自定义类或命名空间 [配置使用Yii2 autoloader]...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 空调支架生锈会不会断掉
- 下一篇: php贝叶斯,php – 将单个概率与朴