Для целей этих правил разрешения вот несколько важных определений:
Неполное имя
Это идентификатор без разделителя пространства имен, напримерFoo
Полное имя
Это идентификатор с разделителем пространства имен, напримерFoo\Bar
Полное имя
Это идентификатор с разделителем пространства имен, который начинается с разделителя пространства имен, например \Foo\Bar
. Пространство имен \Foo
также является полным именем.
Относительное имя
Это идентификатор, начинающийся с namespace
, например namespace\Foo\Bar
.
Имена разрешаются в соответствии с этими правилами разрешения:
- Полные имена всегда разрешаются в имя без начального разделителя пространства имен. Например,
\A\B
разрешаетA\B
. - Относительные имена всегда разрешаются в имя
namespace
, замененное текущим пространством имен. Если имя встречается в глобальном пространстве имен,namespace\
префикс удаляется. Например ,namespace\A
внутреннее пространство именX\Y
разрешается вX\Y\A
. Одно и то же имя внутри глобального пространства имен разрешается вA
. - Для полных имен первый сегмент имени переводится в соответствии с текущей таблицей импорта класса/пространства имен. Например, если пространство имен
A\B\C
импортируется какC
, имяC\D\E
преобразуется вA\B\C\D\E
. - Для полных имен, если не применяется правило импорта, к имени добавляется текущее пространство имен. Например, имя
C\D\E
внутри namespaceA\B
разрешается вA\B\C\D\E
. - Для неквалифицированных имен имя переводится в соответствии с текущей таблицей импорта для соответствующего типа символа. Это означает, что имена классов переводятся в соответствии с таблицей импорта классов/пространств имен, имена функций — в соответствии с таблицей импорта функций, а константы — в соответствии с таблицей импорта констант. Например, после
use A\B\C;
такого использования, какnew C()
разрешение на имяA\B\C()
. Точно так же послеuse function A\B\fn;
использования, такого какfn()
разрешается в имяA\B\fn
. - Для неполных имен, если не применяется правило импорта и имя ссылается на символ, подобный классу, в начало добавляется текущее пространство имен. Например ,
new C()
внутри namespaceA\B
разрешается nameA\B\C
. - Для неполных имен, если не применяется правило импорта и имя ссылается на функцию или константу, а код находится за пределами глобального пространства имен, имя разрешается во время выполнения. Предполагая, что код находится в пространстве имен
A\B
, вот какfoo()
разрешается вызов функции:- Он ищет функцию из текущего пространства имен:
A\B\foo()
. - Он пытается найти и вызвать глобальную функцию
foo()
.
- Он ищет функцию из текущего пространства имен:
Пример #1 Изображено разрешение имен
<?php
namespace A;
use B\D, C\E as F;
// function calls
foo(); // first tries to call "foo" defined in namespace "A"
// then calls global function "foo"
\foo(); // calls function "foo" defined in global scope
my\foo(); // calls function "foo" defined in namespace "A\my"
F(); // first tries to call "F" defined in namespace "A"
// then calls global function "F"
// class references
new B(); // creates object of class "B" defined in namespace "A"
// if not found, it tries to autoload class "A\B"
new D(); // using import rules, creates object of class "D" defined in namespace "B"
// if not found, it tries to autoload class "B\D"
new F(); // using import rules, creates object of class "E" defined in namespace "C"
// if not found, it tries to autoload class "C\E"
new \B(); // creates object of class "B" defined in global scope
// if not found, it tries to autoload class "B"
new \D(); // creates object of class "D" defined in global scope
// if not found, it tries to autoload class "D"
new \F(); // creates object of class "F" defined in global scope
// if not found, it tries to autoload class "F"
// static methods/namespace functions from another namespace
B\foo(); // calls function "foo" from namespace "A\B"
B::foo(); // calls method "foo" of class "B" defined in namespace "A"
// if class "A\B" not found, it tries to autoload class "A\B"
D::foo(); // using import rules, calls method "foo" of class "D" defined in namespace "B"
// if class "B\D" not found, it tries to autoload class "B\D"
\B\foo(); // calls function "foo" from namespace "B"
\B::foo(); // calls method "foo" of class "B" from global scope
// if class "B" not found, it tries to autoload class "B"
// static methods/namespace functions of current namespace
A\B::foo(); // calls method "foo" of class "B" from namespace "A\A"
// if class "A\A\B" not found, it tries to autoload class "A\A\B"
\A\B::foo(); // calls method "foo" of class "B" from namespace "A"
// if class "A\B" not found, it tries to autoload class "A\B"
?>
0 комментариев