2012-08-14 181 views
3

在試驗spl_autoload,命名空間和動態類名時,我遇到了一個「奇怪」的事情。我使用PHP 5.3.2,像這樣調用自動加載PHP命名空間和動態類名

set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils"); 
spl_autoload_extensions(".class.php"); 
spl_autoload_register(); 

現在到了核心。建議如下代碼:

new \User\Student; 
$name="\User\Student"; 
new $name(); 

這工作正常,file classes/user/student.class.php成功加載,兩個構造都成功。然而,有點不同的用法:

$name="\User\Student"; 
new $name(); 
new \User\Student; 

失敗的「..類\用戶\學生無法加載...」。我建議它以某種方式與靜態/動態名稱空間分辨率有關。但是,我不認爲這兩者之間應該有什麼區別,除了它們在(編譯與運行時)處理的時間之外。

感謝您的任何解釋。

+2

嘗試刪除字符串中的前導反斜槓。動態類名始終是完全合格的,因此不鼓勵在其中添加反斜槓。 – NikiC 2012-08-14 10:55:08

回答

4

這裏的「問題」實際上處於比SPL更低的水平,也可以用__autoload()來看。這是在代碼的最佳證明:

function __autoload ($class) { 
    echo "Loading $class\n"; 
} 

new Test; 
// displays "Loading Test" 

$var = 'Test'; 
new $var; 
// displays "Loading Test" 

// However, when we introduce namespaces... 

new \This\Is\A\Test; 
// displays "Loading This\Is\A\Test" 

$var = '\This\Is\A\Test'; 
new $var; 
// displays "Loading \This\Is\A\Test" 

注意如何在引進的時候命名空間,領先的斜線不傳遞給函數的靜態調用的時候,卻是動態調用時。

的解決方案,因此是做任何的這些相當簡單的事情:

  • 從動態類名稱實例刪除前導斜線。
  • 裹默認spl_autoload()功能如下:
set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils"); 
spl_autoload_extensions(".class.php"); 
spl_autoload_register(function($class) { 
    spl_autoload(ltrim($class, '\\')); 
}); 

當然,如果你這樣做,你也可以去掉調用spl_autoload_extensions(),只是傳遞".class.php"字符串的spl_autoload()

第二個參數