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


(PHP 5 >= 5.3.0)

Для этих правил здесь приведены несколько важных определений:

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

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

Полное имя

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

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

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

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

  1. Вызовы абсолютных функций, классов или констант разрешаются во время компиляции. Например, new \A\B разрешается в класс A\B.
  2. Все неполные и полные имена (не абсолютные) переводятся в процессе компиляции в соответствии с текущими правилами импорта. Например, если пространство имен A\B\C заимпортировано как C, вызов C\D\e() преобразуется к A\B\C\D\e().
  3. Внутри пространства имен все полные имена, не переведенные в соответствии с правилами импорта, получают префикс текущего пространства имен. Например, если происходит вызов C\D\e(), он преобразуется внутри пространства имен A\B к A\B\C\D\e().
  4. Неполные имена классов преобразуются в процессе компиляции в соответствии с текущими правилами импорта (полное имя заменено на короткое импортируемое имя). Например, если пространство имен A\B\C заимпортировано как C, выражение new C() преобразовывается к выражению new A\B\C().
  5. Внутри пространства имен (скажем, A\B), вызовы к неполным именам функций преобразуются во время исполнения. Вот, к примеру, как преобразуется вызов функции foo():
    1. Производится поиск функции из текущего пространства имен: A\B\foo().
    2. PHP пытается найти и вызвать функцию глобального пространства foo().
  6. Внутри пространства имен (скажем, A\B), вызовы к неполным или полным именам классов (неабсолютным) преобразуются во время исполнения. Вот как выражение new C() или new D\E() преобразуется. Для new C():
    1. Ищется класс из текущего пространства имен: A\B\C.
    2. Производится попытка автозагрузки A\B\C.
    Для new D\E():
    1. Ищется класс с помощью префиксации текущего пространства имен: A\B\D\E.
    2. Производится попытка автозагрузки A\B\D\E.
    Для обращения к любому глобальному классу в глобальном пространстве, должно использоваться его абсолютное имя new \C().

Пример #1 Примеры разрешения имен

<?php
namespace A;
use 
B\DC\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"
?>