來源:互聯網
上載者:User
關鍵字
php
namespaces
autoload
thinkphp
laravel
假設我的項目其中的一個目錄:
app== site==== controller====== IndexController.php====== AccessController.php== api==== controller====== PostController.php
假設 IndexController.php 的內容:
namespace app\site\controller;class IndexController { // some code}
項目是單入口,包含了 function autoload($className),我的問題:
假設項目約定了 namespace 中的名稱必須和檔案夾名稱一致,並且類名稱也和類檔案同名(不包含底線等奇怪的字元),那這樣的話,$className 其實只需要把右斜杠換成 DIRECTORY_SEPARATOR 就可以找到對應的類檔案了,比如:
$obj = new \app\site\controller\IndexController();
或者
class TestClass extends \app\site\controller\IndexController {}
那 autoload 實際找到的就是 /app/site/controller/IndexController.php。
既然這樣,那為什麼 thinkphp 裡面的 Think 類還要 $_map 呢?類似的還有 laravel 裡的:
autoload_namespaces.phpautoload_classmap.phpautoload_psr4.php
比如這個是 autoload_psr4.php 裡的內容:
$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array( 'yii\\swiftmailer\\' => array($vendorDir . '/yiisoft/yii2-swiftmailer'), 'yii\\gii\\' => array($vendorDir . '/yiisoft/yii2-gii'), 'yii\\faker\\' => array($vendorDir . '/yiisoft/yii2-faker'), 'yii\\debug\\' => array($vendorDir . '/yiisoft/yii2-debug'), 'yii\\composer\\' => array($vendorDir . '/yiisoft/yii2-composer'), 'yii\\codeception\\' => array($vendorDir . '/yiisoft/yii2-codeception'), 'yii\\bootstrap\\' => array($vendorDir . '/yiisoft/yii2-bootstrap'), 'yii\\' => array($vendorDir . '/yiisoft/yii2'), 'cebe\\markdown\\' => array($vendorDir . '/cebe/markdown'), 'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),);
這裡面通過數組定義的映射有什麼作用啊?
回複內容:
假設我的項目其中的一個目錄:
app== site==== controller====== IndexController.php====== AccessController.php== api==== controller====== PostController.php
假設 IndexController.php 的內容:
namespace app\site\controller;class IndexController { // some code}
項目是單入口,包含了 function autoload($className),我的問題:
假設項目約定了 namespace 中的名稱必須和檔案夾名稱一致,並且類名稱也和類檔案同名(不包含底線等奇怪的字元),那這樣的話,$className 其實只需要把右斜杠換成 DIRECTORY_SEPARATOR 就可以找到對應的類檔案了,比如:
$obj = new \app\site\controller\IndexController();
或者
class TestClass extends \app\site\controller\IndexController {}
那 autoload 實際找到的就是 /app/site/controller/IndexController.php。
既然這樣,那為什麼 thinkphp 裡面的 Think 類還要 $_map 呢?類似的還有 laravel 裡的:
autoload_namespaces.phpautoload_classmap.phpautoload_psr4.php
比如這個是 autoload_psr4.php 裡的內容:
$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array( 'yii\\swiftmailer\\' => array($vendorDir . '/yiisoft/yii2-swiftmailer'), 'yii\\gii\\' => array($vendorDir . '/yiisoft/yii2-gii'), 'yii\\faker\\' => array($vendorDir . '/yiisoft/yii2-faker'), 'yii\\debug\\' => array($vendorDir . '/yiisoft/yii2-debug'), 'yii\\composer\\' => array($vendorDir . '/yiisoft/yii2-composer'), 'yii\\codeception\\' => array($vendorDir . '/yiisoft/yii2-codeception'), 'yii\\bootstrap\\' => array($vendorDir . '/yiisoft/yii2-bootstrap'), 'yii\\' => array($vendorDir . '/yiisoft/yii2'), 'cebe\\markdown\\' => array($vendorDir . '/cebe/markdown'), 'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),);
這裡面通過數組定義的映射有什麼作用啊?
composer裡的自動載入可以支援四種規範,psr-0(autoload_namespaces.php),psr-4,class-map,還有files,你如果自己寫代碼,這樣約定好了,命名空間和路徑保持一致,然後autoload載入按路徑載入,當然不需要classmaps,但是很多類庫是其他人寫的,每個人習慣不一樣,有的人喜歡psr-4,有的人喜歡psr-0,(大家規範都一樣,聲明的命名空間和路徑不一樣)時,就需要你說的 Classmap了,你可以看下composer的loader類
laravel裡面的autoload_psr4.php是composer根據各個包的composer.json自動產生的,你研究一下composer就明白了
自動載入不止是你看到的能直接
$obj = new \app\site\controller\IndexController();
這些都已經是自動載入後的結果了。
如果沒有自動載入,你這樣子根本不能實現對象。
你脫離架構再這麼寫看看?
composer的自動載入是根據psr規則來的。
舉個小例子:
如果你要實現一個工廠類,自動載入該如何??
題主可以試一下,就知道架構為什麼要這麼做了。
Composer的自動載入還可以自訂映射的,不一定是按平常的目錄自動載入,可以看下Composer的文檔,架構那一章,有說明每一個key的含義。