Я столкнулся с «странной» вещью, экспериментируя с spl_autoload, пространствами имен и динамическими именами классов. Я использую PHP 5.3.2, вызываю автозагрузку, как это
set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils"); spl_autoload_extensions(".class.php"); spl_autoload_register();
Теперь к сути. Предложите следующий код:
new \User\Student; $name="\User\Student"; new $name();
Это отлично работает, файлы классов / user / student.class.php загружаются успешно, обе конструкции успешны. Однако, немного другое использование:
$name="\User\Student"; new $name(); new \User\Student;
не удается выполнить «..Class \ User \ Student не может быть загружен …». Я полагаю, что это должно быть связано с разрешением статического / динамического пространства имен каким-то образом. Тем не менее, я не думаю, что между этими двумя должно быть различие, за исключением времени, в течение которого они обрабатываются (компиляция или время выполнения).
Спасибо за любое объяснение.
«Проблема» здесь на самом деле находится на более низком уровне, чем SPL, и также можно увидеть с помощью __autoload()
. Это лучше всего демонстрируется в коде:
function __autoload ($class) { echo "Loading $class\n"; } new Test; // displays "Loading Test" $var = 'Test'; new $var; // displays "Loading Test" // However, when we introduce namespaces... new \This\Is\A\Test; // displays "Loading This\Is\A\Test" $var = '\This\Is\A\Test'; new $var; // displays "Loading \This\Is\A\Test"
Обратите внимание, как при введении пространств имен ведущая косая черта не передается функции при вызове статически, но она называется динамически.
Поэтому решение состоит в том, чтобы выполнить любую из этих довольно простых вещей:
spl_autoload()
по умолчанию следующим образом: set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils"); spl_autoload_extensions(".class.php"); spl_autoload_register(function($class) { spl_autoload(ltrim($class, '\\')); });
Конечно, если вы это сделаете, вы также можете удалить вызов spl_autoload_extensions()
и просто передать строку ".class.php"
ко второму аргументу spl_autoload()