Правила разрешения имён

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Для целей этих правил разрешения приведём важные определения:

Определения имени пространства имён
Неполное имя

Идентификатор без разделителя пространств имён, например Foo

Полное имя

Идентификатор с разделителем пространств имён, например Foo\Bar

Абсолютное имя

Идентификатор с разделителем пространств имён, который начинается с разделителя пространств имён, например \Foo\Bar. Пространство имён \Foo — также абсолютное имя.

Относительное имя

Идентификатор, который начинается с ключевого слова namespace, например namespace\Foo\Bar.

Имена разрешаются по следующим правилам:

  1. Абсолютные имена разрешаются в имя без ведущего разделителя пространства имён. Например, \A\B разрешается в A\B.
  2. Относительные имена разрешаются в имя с заменой ключевого слова namespace текущим пространством имён. Если имя встречается в глобальном пространстве имён, префикс namespace\ удаляется. Например, имя namespace\A внутри пространства имён X\Y разрешается в X\Y\A. То же имя в глобальном пространстве имён разрешается в A.
  3. В полных именах первый сегмент имени преобразовывается с учётом текущей таблицы импорта класса или пространства имён. Например, если пространство имён A\B\C импортировано как C, то имя C\D\E преобразуется в A\B\C\D\E.
  4. В полных именах, если не применялось правило импорта, текущее пространство имён добавляется к имени. Например, имя C\D\E внутри пространства имён A\B разрешится в A\B\C\D\E.
  5. Неполные имена преобразовываются с учётом текущей таблицы импорта и типа элемента. То есть имена как у классов преобразовываются с учётом таблицы импорта классов или пространств имён, имена функций — с учётом таблицы импорта функций, а константы — таблицы импорта констант. Например, при записи use A\B\C;, вызов new C() разрешается в A\B\C(). Аналогично, при записи use function A\B\foo; вызов foo() разрешается в A\B\foo.
  6. В начало неполных имён, если не применялось правило импорта и имя относится к элементу с именем как у класса, добавляется текущее пространство имён. Например, имя класса в выражении new C() внутри пространства имён A\B разрешится в имя A\B\C.
  7. В неполных именах, если не применялось правило импорта и имя относится к функции или константе, а код лежит за пределами глобального пространства имён, имя разрешается при выполнении. Вот как разрешится вызов функции foo() в коде в пространстве имён A\B:
    1. Выполняется поиск функции из текущего пространства имён: A\B\foo().
    2. 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

?>