2016-03-22 70 views
1

我對如何在Composer中使用psr-4 autoloading有點困惑。比方說,我有一個文件夾結構是這樣的:爲什麼在使用Composer使用psr-4自動加載時指定名稱空間?

/ 
|- Core/ 
| - Router.php 
|- App/ 
| - Models 
|  User.php 
|- composer.json 

基本上,在項目的根:composer.json;一個核心文件夾包含一個路由器 PHP類; App包含的文件夾型號包含用戶類的文件夾。

Router類看起來是這樣的:

<?php 
namespace Core; 

class Router { 
} 

和用戶類看起來是這樣的:

<?php 
namespace App\Models; 

class User { 
} 

這樣我就可以自動加載這些類使用作曲家PSR-4自動加載機,我可以做這在composer.json中:

{ 
    "autoload": { 
     "psr-4": { 
      "Core\\": "Core", 
      "App\\Models\\": "App/Models" 
     } 
    } 
} 

所以我可以使用這些類而不需要它們(運行後寧composer dump-autoload)這樣的:

$router = new Core\Router(); 
$user = new App\Models\User(); 

它工作沒有問題。

然而,我也能做到這一點在composer.json:

{ 
    "autoload": { 
     "psr-4": { 
      "": "" 
     } 
    } 
} 

其中,根據所述文檔是一個回退目錄,其中任何名稱空間可以是,相對於根。因此,通過在composer自動加載器中創建這個「空」條目,我相信它說「從根開始,在任何目錄中查找任何名稱空間中的類」,我可以自動加載我的任何類,如果我按照正確的文件夾命名/名稱空間結構。

所以我的問題是,如果後者工作並且簡單得多,我爲什麼要這樣做?這是一種表演嗎?還是有另一個原因?

+0

我不知道......爲什麼會* *您?我不會。你爲什麼認爲你應該? – deceze

+2

對於一個人來說,如果你有一天決定將你所有的模型移動到其他地方,使用前一種方法你可以改變一行,使用後一種方法,你需要重命名所有的命名空間。 – apokryfos

+1

如果你在custom/library/src中有一個自定義包,那麼你可能不想做一個名爲'custom \ library \ src'的命名空間,而只是'Library'。這一切都歸結於您的項目中的約定,除了apokyrfos所製造的點外。 – Devon

回答

3

爲什麼你不應該總是做"psr-4": {"": ""}

原因1:性價比較高。該定義說,對於需要自動加載的每個類,Composer應該查看根目錄。這些類不僅是你的包中的類,而且也是所有其他類。

作曲家試圖通過記住沒有結果的搜索來優化這種努力,但是如果您使用相同的前綴加載另一個類,則這隻會付出代價。

原因2:PSR-4的本質是,您不必將整個命名空間路徑映射到目錄路徑。假設你有一個包,有喜歡\Vendor\Template\Escaping\Output\*一個非常具體的組類交易,而不是其他(有小包裝可以更容易地重新使用它們無需增加太多的代碼),你可以有他們在src/Vendor/Template/Escaping/Output/AnyClass.php和定義

"psr-4": { 
     "\\Vendor\\Template\\Escaping\\Output\\": "src/Vendor/Template/Escaping/Output/" 
} 

你也可以把全班學生分成src/AnyClass.php和定義

"psr-4": { 
     "\\Vendor\\Template\\Escaping\\Output\\": "src/" 
} 

這顯著縮短了目錄路徑,稍微提高速度(我認爲 - 有沒有數字雖然),但主要是提高發展中國家由於事至 少開空文件夾。

在同一個包中同時包含Core名稱空間和App命名空間,這讓我產生懷疑:爲什麼每個包都沒有一個包?

+0

很好的解釋,謝謝。我錯誤地認爲psr-4必須具有匹配的文件夾和命名空間。至於核心和應用程序的單獨包,好點,雖然他們只是我爲這個問題選擇的例子;-) –

+0

一個問題:爲什麼PSR-4需要名稱空間和目錄,爲什麼他們不滿意名稱空間只要 ? –

+0

@AmarjeetChaudhary您可以完全自由地根據自己的喜好定義PSR-4結構的起始目錄,但是您必須以某種方式提供目錄,因爲您將如何知道從哪裏開始尋找?定義項目的根目錄不是合理的默認值,因爲通常會存儲像'README','composer.json','.gitignore'這樣的元數據。將任何其他目錄定義爲默認值也會產生如何同意名稱的問題。 'src'似乎是許多項目的常見選擇,但並不是每個人都必須這樣做。 – Sven

-3

PSR-4是一種將命名空間轉換爲物理目錄的標準。

1

通常,在使用作曲家時,您只有一個用於自己項目的文件夾。然後你只需要指定一個名字空間。

考慮,你會重新安排你的文件結構,以

/ 
|- lib/ 
| - Core/ 
|  - Router.php 
| - App/ 
|  - Models 
|   User.php 
|- composer.json 

,改變你的composer.json到

{ 
    "autoload": { 
     "psr-4": { 
      "MyApp\\": "lib/" 
     } 
    } 
} 

,那麼你只有一個指定的命名空間,你不需要添加任何進一步的命名空間。你可以打電話給你的類是這樣的:

$router = new \MyApp\Core\Router; 
$user = new \MyApp\App\Models\User; 

或像這樣:

namespace MyApp; 
$router = new Core\Router; 
$user = new App\Models\User; 
相關問題