Правила разрешения имен
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Для этих правил здесь приведены несколько важных определений:
-
Определения имени пространства имен
- Неполное имя
-
Это идентификатор без разделителя пространств имен, например,
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
внутри пространства именA\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()
внутри пространства именA\B
разрешаются какA\B\C
. -
Неполные имена, если отсутствуют ограничения в таблице импорта и если они используются
как функция или константа, а код находится не в глобальном пространстве имен, имена
разрешаются во время исполнения. Например код, в пространстве имен
A\B
, вызывающий функциюfoo()
, разрешается так:-
Производится поиск функции из текущего пространства имен:
A\B\foo()
. -
PHP пытается найти и вызвать функцию глобального пространства
foo()
.
-
Производится поиск функции из текущего пространства имен:
Пример #1 Примеры разрешения имен
<?php
namespace A;
use B\D, C\E as F;
// вызовы функций
foo(); // сперва пытается вызвать "foo", определенную в пространстве имен "A",
// затем вызывает глобальную функцию "foo"
\foo(); // вызывает функцию "foo", определенную в глобальном пространстве
my\foo(); // вызывает функцию "foo", определенную в пространстве "A\my"
F(); // сперва пытается вызвать "F", определенную в пространстве имен "A",
// затем вызывает глобальную функцию "F"
// ссылки на классы
new B(); // создает объект класса "B", определенного в пространстве имен "A".
// если не найден, то пытается сделать автозагрузку класса "A\B"
new D(); // используя правила импорта, создает объект класса "D", определенного в пространстве имен "B"
// если не найден, то пытается сделать автозагрузку класса "B\D"
new F(); // используя правила импорта, создает объект класса "E", определенного в пространстве имен "C"
// если не найден, то пытается сделать автозагрузку класса "C\E"
new \B(); // создает объект класса "B", определенного в глобальном пространстве,
// если не найден, то пытается сделать автозагрузку класса "B"
new \D(); // создает объект класса "D", определенного в глобальном пространстве,
// если не найден, то пытается сделать автозагрузку класса "D"
new \F(); // создает объект класса "F", определенного в глобальном пространстве,
// если не найден, то пытается сделать автозагрузку класса "F"
// статические методы/функции пространства имен из другого пространства имен
B\foo(); // вызывает функцию "foo" из пространства имен "A\B"
B::foo(); // вызывает метод "foo" из класса "B", определенного в пространстве имен "A"
// если класс "A\B" не найден, то пытается сделать автозагрузку класса "A\B"
D::foo(); // используя правила импорта, вызывает метод "foo" класса "D", определенного в пространстве имен "B"
// если класс "B\D" не найден, то пытается сделать автозагрузку класса "B\D"
\B\foo(); // вызывает функцию "foo" из пространства имен "B"
\B::foo(); // вызывает метод "foo" класса "B" из глобального пространства
// если класс "B" не найден, то пытается сделать автозагрузку класса "B"
// статические методы/функции пространства имен из текущего пространства имен
A\B::foo(); // вызывает метод "foo" класса "B" из пространства имен "A\A"
// если класс "A\A\B" не найден, то пытается сделать автозагрузку класса "A\A\B"
\A\B::foo(); // вызывает метод "foo" класса "B" из пространства имен "A"
// если класс "A\B" не найден, то пытается сделать автозагрузку класса "A\B"
?>