2011-09-18 144 views
3

我一直在使用PHP很長一段時間,但現在開始嘗試使用新的語言功能,如命名空間。我有一個關於自動加載的問題,我無法在我的網頁搜索中找到適當的答案。自動加載和命名空間

假設我有不同的命名空間中的類:

namespace foo\bar\baz; 

class Quux 
{ 
} 

namespace fred\barney\wilma; 

class Betty 
{ 
} 

然後假設我有這樣的假設,有一個1自動加載磁帶機:

function autoload ($className) 
{ 
    $className = str_replace ('\\', DIRECTORY_SEPERATOR, $className); 
    include ($className . 'php'); 
} 

spl_autoload_register ('autoload'); 

是否充分:命名空間和目錄結構之間的一對一映射合格的命名空間在所有情況下都會傳遞給自動加載器,還是自動加載器需要考慮當前使用的名稱空間?

例如,如果我做到以下幾點:

$a = new \foo\bar\baz\Quux; 
$b = new \fred\barney\wilma\Betty; 

自動加載磁帶機應該可以正常工作。

但是,如果我做了以下事情呢?

use \foo\bar\baz as FBB; 
$a = new Quux; 
$b = new \fred\barney\wilma\Betty; 

當試圖實例化一個新QUUX,會自動加載磁帶機仍然得到\foo\bar\baz\Quux類名的說法?或者它應該得到FBB\Quux,甚至只是Quux

如果是後者,是否可以通過使用__NAMESPACE__或其他類似的機制來確定類應該位於我的自動裝載器中的命名空間?

+0

那麼你試過的結果是什麼? – xdazz

回答

4

自動加載器將獲得foo\bar\baz\Quux作爲類名稱參數。

命名空間名稱定義
限定名稱
這是一個標識符 沒有命名空間分隔,如富

合格名字
這是一個命名空間分隔符的標識符,例如 爲Foo \ Bar

標準名稱
這是一個標識符,其名稱空間分隔符 開頭w使用命名空間分隔符,例如\ Foo \ Bar。 命名空間\ Foo也是一個完全限定名稱。

而且規則是:

所有不合格和合格的名稱(不完全合格的名稱)是 根據當前的導入規則在編譯時轉換。例如,對於 示例,如果將名稱空間A \ B \ C導入爲C,則調用C \ D \ e()爲 ,並將其轉換爲A \ B \ C \ D \ e()。

+1

對不起,我不得不不接受這個答案。當我嘗試實際實現一個像這樣工作的自動加載器時,我發現'new/foo/bar/baz()'可以正常工作,但是如果我使用了/ foo/bar, new baz()'我只會讓baz被傳遞給我的自動加載器。 – GordonM

+0

@GordonM你應該做'使用foo \ bar \ baz;新巴茲();'。 – xdazz

+1

是的,我只是想通了。對不起,我只是完全誤解了use關鍵字的工作方式。 – GordonM

0

你會得到一個完全合格的命名空間名稱(沒有前導反斜槓)。

這也適用於所有其他動態語言結構和功能在PHP中:

如果你寫$obj = new $class$class必須是完全合格的,並且不使用任何定義的別名。
如果您編寫class_exists($class)$class也必須完全合格。
同樣適用於自動加載:它傳遞完全限定名稱。

(唯一的例外,我知道的是define功能,它可以同時使用完全合格的名字,而且還使用不合格的名稱,在這種情況下,它會在當前名字空間中定義常量定義。)