2011-05-27 35 views
0

我想我的實例化類這樣做的:PHP:與不完全合格的命名空間動態實例

use somedir\http as Http; 

$S_bodyWriterType = 'Http\\' . strtolower($S_requestBodyPayloadType) . '\\RequestBodyWriter'; 
$this->_O_requestBodyWriter = new $S_bodyWriterType; 

它說的類不存在。然而,將工作(這裏不涉及字符串):

$this->_O_requestBodyWriter = new Http\xml\RequestBodyWriter; 

而這也將工作當然(命名空間是完全合格的):

$S_bodyWriterType = 'somedir\http\\' . strtolower($S_requestBodyPayloadType) . '\\' . 'RequestBodyWriter'; 
$this->_O_requestBodyWriter = new $S_bodyWriterType; 

,我肯定會更喜歡使用縮短的命名空間,而不是必須在代碼庫的不同位置編寫長的完全限定名稱空間,並且必須在目錄位置移動的情況下全部更改它們。現在我已經把我的頭髮拉了一會兒。

感謝您的幫助!

+0

「它說班不存在。」 =>哪個班?向我們顯示錯誤消息。無論如何,你只保存8個字符('somedir \')。你可以爲它設置一個常量(感覺也有點乾淨;))。 – KingCrunch 2011-05-27 10:08:36

+0

致命錯誤:未找到'Http \ xml \ RequestBodyWriter'類...並且,是的,我正在考慮使用常量作爲解決方法。我偶然發現該評論「當作爲字符串使用時,我們需要完全限定的名稱,因爲我們不知道參數來自哪裏。」在http://bugs.php.net/bug.php?id=51126上。我想這是動態實例與串... – user772843 2011-05-27 11:30:19

回答

0

OK,你自己提供的Bug report)但那事實:如果你在一個字符串定義一個類的名稱,它不是說,該對象在同一環境中創建。

namespace y { 
    use a\b as B; 
    $GLOBALS['class'] = 'B\\MyClass'; 
} 
namespace z { 
    use k\l as B; 
    $classname = $GLOBALS['class']; 
    $a = new $classname; 
} 

因此,您需要定義完全符合字符串的類名。我建議使用(namespace- /講座)常數

use a\b as B; 
const NAMESPACE_B = '\\a\\b'; 
$classname = NAMESPACE_B . '\\MyClass'; 

如果要實例化的類是在子名字空間,記住,僞不變__NAMESPACE__總是存在的;

namespace a; 
use a\b as B; 
$classname = __NAMESPACE__ . '\\b\\MyClass'; 

你的情況附加我建議建立一個工廠

use somedir\http as Http; 
class RequestBodyWriterFactory { 
    public function create($type) { 
    $classname = __NAMESPACE__ . "\\$type\\RequestBodyWriter"; 
    return new $classname; 
    } 
} 

// somewere else 
$this->_O_requestBodyWriter = $this->factory->create(strtolower($S_requestBodyPayloadType)); 

上創建什麼和如何創建它這樣你有更多的控制。

+0

工廠選項聽起來不錯,謝謝! – user772843 2011-05-27 12:44:16