我想让我的班级做好准备:
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 :(得分:0)
好的,你自己提供了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- / class-)常量
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));
通过这种方式,您可以更好地控制创建的内容及其创建方式。