I'd like to instanciate my class doing :
use somedir\http as Http;
$S_bodyWriterType = 'Http\\' . strtolower($S_requestBodyPayloadType) . '\\RequestBodyWriter';
$this->_O_requestBodyWriter = new $S_bodyWriterType;
It says the class does not exist. However THAT would work (no string involved here) :
$this->_O_requestBodyWriter = new Http\xml\RequestBodyWriter;
And that would also work of course (the namespace is fully qu开发者_运维问答alified) :
$S_bodyWriterType = 'somedir\http\\' . strtolower($S_requestBodyPayloadType) . '\\' . 'RequestBodyWriter';
$this->_O_requestBodyWriter = new $S_bodyWriterType;
i'd definitely prefer to use shortened namespaces instead of having to write long, fully-qualified namespaces in different places of the codebase and having to change them all in case the directory location moves. I've been pulling my hair off for a while now over this.
Thanks for help !
OK, you provided the Bug report yourself ;) But thats the fact: If you define a classname in a string, its not said, that the object is created in the same context.
namespace y {
use a\b as B;
$GLOBALS['class'] = 'B\\MyClass';
}
namespace z {
use k\l as B;
$classname = $GLOBALS['class'];
$a = new $classname;
}
Thus you need to define classnames in string full qualifed. I suggest to use (namespace-/class-)constants
use a\b as B;
const NAMESPACE_B = '\\a\\b';
$classname = NAMESPACE_B . '\\MyClass';
If the class you want to instanciate is in a subnamespace, remember, that the pseudo-constant __NAMESPACE__
always exists;
namespace a;
use a\b as B;
$classname = __NAMESPACE__ . '\\b\\MyClass';
Additional in your case I suggest to create a factory
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));
This way you have more control on what is created and how its created.
精彩评论