Создание экземпляра PHP stdClass в моем пространстве имен — фатальная ошибка

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

Мой код будет написан в его собственном пространстве имен, в то время как код CMS не использует пространство имен, что в основном означает, что он существует в глобальном пространстве имен.

Внутри моего кода я создаю новый stdClass:

$var = new stdClass();

С этим кодом место всегда выдает фатальную ошибку:

Fatal error: Class 'MyNamespace\something\StdClass' not found in /some/rather/long/path/to/class.php on line 123

Создание stdClass вот так решает эту проблему:

$var = new \stdClass();

Поскольку я все еще плохо знаком с пространствами имен, я не совсем уверен, в чем здесь проблема?

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

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

Если бы кто-нибудь мог объяснить, что здесь происходит, я был бы очень счастлив.

0

Решение

Вы, кажется, понимаете концепцию пространств имен, и вы движетесь в правильном направлении в своем анализе того, что происходит.

Когда вы работаете внутри пространства имен, вы можете ссылаться на имена как неквалифицированный, квалифицированный, а также Полностью квалифицированный.

Когда вы создаете пространство имен, вы говорите PHP организовывать (и разрешать) имена ваших классов, функций, методов и т. Д. Вне той же области, в которой встроенный код PHP живет вместе с любым другим кодом за своим собственным пространством имен. Вы можете упорядочить свой код и избежать конфликтов имен между библиотеками и встроенными функциями PHP.

Вот краткое описание того, как имена разрешаются:

  • Если вы пытаетесь разрешить имя в том же пространстве имен, вы можете использовать неквалифицированное имя. Так для класса \Foo\Bar\Baz ты можешь использовать new Baz(); пока вы находитесь в пространстве имен \Foo\Bar,

  • Если вы пытаетесь разрешить имя, которое находится ниже в том же родительском пространстве имен, вы можете использовать квалифицированное имя. Так для класса \Foo\Bar\Baz вам нужно будет использовать new Bar\Baz(); если бы вы были в пространстве имен \Foo,

  • Если вы пытаетесь разрешить имя, которое не находится в вашем пространстве имен или находится в глобальном пространстве имен (встроенный компонент PHP), тогда вы должны использовать полное имя. Если вы находитесь в пространстве имен \Foo\Bar и вы хотите использовать что-то вроде mysqli класс, вам нужно будет назвать его по полному имени. например new \mysqli() Ваш вопрос выше — прекрасный пример, который иллюстрирует это. Аналогично, если вам нужен доступ к классу в совершенно другом пространстве имен, вам также понадобится полное имя: new \Third\Party\AppClass();

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

Если вам когда-нибудь понадобится выяснить, в каком пространстве имен вы находитесь, оно будет в __NAMESPACE__ постоянная.

Если вы еще этого не прочитали, вот документация по разрешению имен в PHP: http://php.net/manual/en/language.namespaces.rules.php

4

Другие решения

Код оценивается в вашем пространстве имен, и stdClass там не существует. Вы эффективно отвечаете на свой вопрос с вашим предположением.

1

Ваше предположение верно. Посмотрите комментарии в разделе «ссылки на классы» примера № 1 на этой странице.

http://php.net/manual/en/language.namespaces.rules.php

1
По вопросам рекламы [email protected]