不能在自动加载器中使用名称空间

问题描述 投票:0回答:1

[使用自动加载器“ 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();

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";
  }

}
php namespaces autoloader php-7.3
1个回答
1
投票

您的自动加载器为所有使用名称空间的类都采用基于目录的系统,即使这不是故意的。原因是名称空间分隔符与目录分隔符相同(或相似度足以使系统在两者之间自动转换)。

执行此操作时:

file_exists($dir . $class_name . $extension)

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

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

© www.soinside.com 2019 - 2024. All rights reserved.