Невозможно использовать пространство имен с автозагрузчиком - PullRequest
0 голосов
/ 26 мая 2020

При использовании автозагрузчика spl_autoload_register я не могу создать экземпляры классов с пространством имен. Он отлично работает для доступа к методам класса, если не использует пространство имен, или просто исключая автозагрузчик. Я намеренно оставил пространство имен для первого класса, чтобы показать ошибку. Все файлы запускаются из одной папки.

Возможная причина ошибки:

Поскольку пространство имен работает без автозагрузчика, я подозреваю, что автозагрузчик добавляет обратную косую черту пути к пространству имен из экземпляра. Если да, то это может быть причиной того, что класс не найден.

Наблюдения:

Автозагрузка загружает классы без ошибок. Доступ к методам класса можно получить, если не использовать путь пространства имен во время создания экземпляра. Если включить классы без автозагрузки, можно создать экземпляр Class_2 с пространством имен.

Если я закомментирую создание Class_2, я получу следующее без ошибок:

Hello from class 1

Сообщение об ошибке:

Hello from class 1PHP Fatal error:  Uncaught Error: Class 'Area_2\Class_2' not found in Xxx/run.php:9

Автозагрузчик:

spl_autoload_register(
    function ($class_name) {

      $directories = ['./'];
      $extension   = ".class.php";

      foreach ( $directories as $dir) {
        if (file_exists($dir . $class_name . $extension)) {
            require_once($dir . $class_name . $extension);
            return;
        }
      }
    }
);

Запустить файл:

include 'autoloader.php';

$class_1 = new Class_1();
$class_1->print_1();


$class_2 = new \Area_2\Class_2(); // Error by using namespace.
$class_2->print_2();

Класс_1:

class Class_1 {

  public function print_1()
  {
    echo "Hello from class 1";
  }

}

Класс_2:

namespace Area_2;

class Class_2 {

  public function print_2()
  {
    echo "Hello from class 2";
  }

}

1 Ответ

1 голос
/ 26 мая 2020

Ваш автозагрузчик предполагает систему на основе каталогов для любых классов, использующих пространство имен, даже если это не предназначено. Причина в том, что разделитель пространства имен такой же, как разделитель каталогов (или достаточно похож, чтобы системы автоматически преобразовывали их между ними). ​​

Когда вы это делаете:

file_exists($dir . $class_name . $extension)

Использование класса Area_2\Class_2, PHP преобразует его в ./Area_2\Class_2.class.php.

По этой причине ваш код ожидает папки.

...