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

(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

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open