2011-05-27 37 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