不能将命名空间与自动加载器一起使用

Cannot use namespace with autoloader

使用自动加载器 "spl_autoload_register" 时,我无法使用命名空间实例化 classes。如果不使用命名空间,或者通过简单地排除自动加载器,它可以很好地访问 class 方法。我故意省略了第一个 class 的名称空间以显示错误。所有文件都来自同一文件夹运行。

错误的可能原因:

由于命名空间在没有自动加载器的情况下工作,我怀疑自动加载器从实例化中添加了命名空间路径的反斜杠。如果是这样,这可能是找不到 class 的原因。

观察:

Autoload 加载 classes 没有错误。 Class 如果在实例化期间不使用命名空间路径,则可以访问方法。如果包含没有自动加载的 classes,则可以使用命名空间实例化 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();

Class_1:

class Class_1 {

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

}

Class_2:

namespace Area_2;

class Class_2 {

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

}

您的自动加载器为任何使用命名空间的 classes 假设一个基于目录的系统,即使它不是预期的。原因是命名空间分隔符与目录分隔符相同(或足够相似,系统会自动在两者之间进行转换)。

当你这样做时:

file_exists($dir . $class_name . $extension)

使用 class Area_2\Class_2、PHP 将其转换为 ./Area_2\Class_2.class.php

因此,您的代码需要文件夹。