#php #namespaces
#php #пространства имен
Вопрос:
Я хотел бы создать экземпляр моего класса, выполняющий :
use somedirhttp as Http;
$S_bodyWriterType = 'Http\' . strtolower($S_requestBodyPayloadType) . '\RequestBodyWriter';
$this->_O_requestBodyWriter = new $S_bodyWriterType;
Он говорит, что класс не существует. Однако ЭТО сработало бы (здесь не задействована строка) :
$this->_O_requestBodyWriter = new HttpxmlRequestBodyWriter;
И это, конечно, тоже сработало бы (пространство имен является полным) :
$S_bodyWriterType = 'somedirhttp\' . strtolower($S_requestBodyPayloadType) . '\' . 'RequestBodyWriter';
$this->_O_requestBodyWriter = new $S_bodyWriterType;
я бы определенно предпочел использовать сокращенные пространства имен вместо того, чтобы писать длинные, полные пространства имен в разных местах кодовой базы и менять их все в случае перемещения местоположения каталога. Я уже некоторое время ломаю голову над этим.
Спасибо за помощь!
Комментарии:
1. «Он говорит, что класс не существует». => Какой класс? Покажите нам сообщение об ошибке. В любом случае, вы сохраняете всего 8 символов (`somedir`). Вы можете установить для него константу (тоже немного чище ;)).
2. Неустранимая ошибка: класс ‘Http xml RequestBodyWriter’ не найден… И хорошо, да, я рассматривал возможность использования константы в качестве обходного пути. Я наткнулся на этот комментарий «При использовании в качестве строки нам нужно полное имя, поскольку мы не знаем, откуда берется параметр». на bugs.php.net/bug.php?id=51126 . Я думаю, это то же самое для динамических экземпляров со строками…
Ответ №1:
Хорошо, вы сами предоставили отчет об ошибке 😉 Но это факт: если вы определяете classname в строке, это не говорит о том, что объект создан в том же контексте.
namespace y {
use ab as B;
$GLOBALS['class'] = 'B\MyClass';
}
namespace z {
use kl as B;
$classname = $GLOBALS['class'];
$a = new $classname;
}
Таким образом, вам нужно определить имена классов в строке с полными параметрами. Я предлагаю использовать константы (namespace- / class-)
use ab as B;
const NAMESPACE_B = '\a\b';
$classname = NAMESPACE_B . '\MyClass';
Если класс, который вы хотите создать, находится в пространстве вложенных имен, помните, что псевдоконстанта __NAMESPACE__
существует всегда;
namespace a;
use ab as B;
$classname = __NAMESPACE__ . '\b\MyClass';
Дополнительно в вашем случае я предлагаю создать фабрику
use somedirhttp 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));
Таким образом, у вас больше контроля над тем, что создается и как это создается.