Я давно работаю с 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__
или какой-либо другой такой механизм?
Автозагрузчик получит foo\bar\baz\Quux
в качестве аргумента имени класса.
Определения имен пространства имен
Неквалифицированное имя
Это идентификатор без разделителя пространства имен, например FooКвалифицированное имя
Это идентификатор с разделителем пространства имен, например Foo \ BarПолностью квалифицированное имя
Это идентификатор с разделителем пространства имен, который начинается с разделителя пространства имен, например \ Foo \ Bar. namespace \ Foo также является полностью квалифицированным именем.
И правило:
Все неквалифицированные и квалифицированные имена (не полностью квалифицированные имена) переводятся во время компиляции в соответствии с действующими правилами импорта. Например, если пространство имен A \ B \ C импортируется как C, вызов C \ D \ e () переводится в A \ B \ C \ D \ e ().
Вы получите полное имя пространства имен (без обратной косой черты).
Это также относится ко всем другим динамическим языковым конструкциям и функциям в PHP:
Если вы пишете $obj = new $class
$class
должен быть полностью квалифицированным и не использовать какие-либо определенные псевдонимы.
Если вы пишете class_exists($class)
$class
также должен быть полностью квалифицирован.
То же самое относится и к автозагрузке: передается полное имя.
(Единственное исключение из этого правила, о котором я знаю, это функция define
, которая может определять константы как с использованием полных имен, так и с использованием неквалифицированного имени, и в этом случае оно будет определено в текущем пространстве имен.)