2013-10-28 83 views
3

以下所有示例都基於保證所有文件都存在於其正確位置。我已經高音檢查過了。使用PHP變量實例化類 - 命名空間問題

(1)未使用的命名空間時,該工作原理:

$a = "ClassName"; 
$b = new $a(); 

這不起作用:

// 'class not found' error, even though file is there 

namespace path\to\here; 
$a = "ClassName"; 
$b = new $a(); 

這是否工作:

namespace path\to\here; 
$a = "path\to\here\ClassName"; 
$b = new $a(); 

所以它似乎命名空間聲明在使用變量實例化類時被忽略。

是否有更好的方法(比我的最後一個例子),所以我不需要通過一些代碼並更改每個變量以包含命名空間?

+0

空間聲明通常在源文件的頂部去一次,不在你需要的變量前面。 –

+0

你可以做的最好的事情就是使用'__namespace__'關鍵字來修改你的*變量名稱空間*,例如'$ a = __namespace__。 「\\類名」;'。不解決問題,但至少現在如果你的名字空間改變了,代碼也會如此。 –

+0

感謝所有的評論和回答。我實際上認爲上面的最後一條評論是最好的方法(除非調用_namespace_有性能問題,我懷疑)。再次感謝這兩個答案,我已經提出了兩個答案。我接受的答案是上面的最後一條評論。 – user2143356

回答

5

命名空間始終是完整類名的一部分。使用一些使用語句,您只會在運行時爲類創建一個別名。

<?php 

use Name\Space\Class; 

// actually reads like 

use Name\Space\Class as Class; 

?> 

的命名空間聲明之前的一類只告訴這個類屬於該命名空間,實例化你仍然需要參考完整的類名(其中包括如前所述的命名空間)PHP解析器。

要回答您的具體問題,不,沒有比您的問題中包含的最後一個示例更好的方法。雖然我會在雙引號字符串逃過那些不好的反斜槓。*

<?php 

$foo = "Name\\Space\\Class"; 
new $foo(); 

// Of course we can mimic PHP's alias behaviour. 

$namespace = "Name\\Space\\"; 

$foo = "{$namespace}Foo"; 
$bar = "{$namespace}Bar"; 

new $foo(); 
new $bar(); 

?> 

*)無需如果使用單引號的字符串逃脫。

1

當一個字符串存儲類的名字,你需要存儲類的全名,不僅是相對於當前命名空間名稱:

<?php 
// global namespace 
namespace { 
    class Outside {} 
} 

// Foo namespace 
namespace Foo { 
    class Foo {} 

    $class = "Outside"; 
    new $class; // works, is the same as doing: 
    new \Outside; // works too, calling Outside from global namespace. 

    $class = "Foo"; 
    new $class; // won't work; it's the same as doing: 
    new \Foo; // trying to call the Foo class in the global namespace, which doesn't exist 

    $class = "Foo\Foo"; // full class name 
    $class = __NAMESPACE__ . "\Foo"; // as pointed in the comments. same as above. 
    new $class; // this will work. 
    new Foo; // this will work too. 
}