Я хочу написать небольшое дополнение для существующей 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
из глобального пространства имен, что как-то вдруг имеет смысл.
Если бы кто-нибудь мог объяснить, что здесь происходит, я был бы очень счастлив.
Вы, кажется, понимаете концепцию пространств имен, и вы движетесь в правильном направлении в своем анализе того, что происходит.
Когда вы работаете внутри пространства имен, вы можете ссылаться на имена как неквалифицированный, квалифицированный, а также Полностью квалифицированный.
Когда вы создаете пространство имен, вы говорите 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
Код оценивается в вашем пространстве имен, и stdClass там не существует. Вы эффективно отвечаете на свой вопрос с вашим предположением.
Ваше предположение верно. Посмотрите комментарии в разделе «ссылки на классы» примера № 1 на этой странице.