автозагрузка и пространства имен - PullRequest
3 голосов
/ 18 сентября 2011

Я давно работаю с PHP, но сейчас начинаю экспериментировать с новыми языковыми функциями, такими как пространства имен. У меня есть вопрос относительно автозагрузки, на который я не смог найти адекватного ответа в своем поиске в сети.

Предположим, у меня есть классы в разных пространствах имен:

namespace foo\bar\baz;

class Quux
{
}

namespace fred\barney\wilma;

class Betty
{
}

Тогда предположим, что у меня был автозагрузчик, который предполагает, что между пространствами имен и структурами каталогов есть соотношение 1: 1:

function autoload ($className)
{
    $className = str_replace ('\\', DIRECTORY_SEPERATOR, $className);
    include ($className . 'php');
}

spl_autoload_register ('autoload');

Передается ли полностью определенное пространство имен автозагрузчику при любых обстоятельствах, или автозагрузчик должен учитывать пространство имен, используемое в настоящее время?

Например, если я сделаю следующее:

$a = new \foo\bar\baz\Quux;
$b = new \fred\barney\wilma\Betty;

автозагрузчик должен работать нормально.

Но что, если я сделаю следующее?

use \foo\bar\baz as FBB;
$a = new Quux;
$b = new \fred\barney\wilma\Betty;

При попытке создания нового Quux автозагрузчик все равно получит \foo\bar\baz\Quux в качестве аргумента имени класса? Или он должен получить FBB\Quux, или даже просто Quux?

Если последнее, могу ли я определить пространство имен, в котором должен находиться класс, из моего автозагрузчика, используя __NAMESPACE__ или какой-либо другой такой механизм?

Ответы [ 2 ]

4 голосов
/ 18 сентября 2011

Автозагрузчик получит foo\bar\baz\Quux в качестве аргумента имени класса.

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

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

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

И правило:

Все неквалифицированные и полные имена (не полные имена) переводятся во время компиляции в соответствии ск текущим правилам импорта.Например, если пространство имен A \ B \ C импортировано как C, вызов C \ D \ e () преобразуется в A \ B \ C \ D \ e ().

0 голосов
/ 18 сентября 2011

Вы получите полностью определенное имя пространства имен (без обратной косой черты).

Это также относится ко всем другим динамическим языковым конструкциям и функциям в PHP:

Если вы пишете $obj = new $class, $class должен быть полностью квалифицированным и не использовать никаких определенных псевдонимов.
Если вы пишете class_exists($class), $class также должен быть полностью квалифицирован.
То же самое относится и к автозагрузке: ему передается полное имя.

(Единственное исключение из этого правила, которое я знаю, - это функция define, которая может определять константы как с использованием полностью определенных имен, так и с использованием неквалифицированного имени, в этом случае оно будет определено в текущем пространстве имен.)

...