PHP: динамический экземпляр с не полностью определенными пространствами имен - PullRequest
0 голосов
/ 27 мая 2011

Я бы хотел, чтобы мой класс выполнял следующие действия:

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;

я бы определенно предпочелиспользуйте сокращенные пространства имен вместо того, чтобы писать длинные, полностью определенные пространства имен в разных местах кодовой базы и менять их все в случае перемещения каталога.Я уже некоторое время стаскиваю волосы из-за этого.

Спасибо за помощь!

1 Ответ

0 голосов
/ 27 мая 2011

ОК, вы предоставили Отчет об ошибке самостоятельно;) Но это факт: если вы определяете имя класса в строке, то не сказано, что объект создан в том же контексте.

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));

Таким образом, вы получаете больше контроля над тем, что создается и как оно создается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...