Правила разрешения имен
(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"
?>