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

Cannot use namespace with autoloader

提问人:Toolbox 提问时间:5/26/2020 最后编辑:Toolbox 更新时间:5/27/2020 访问量:147

问:

使用自动加载器“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 命名空间 自动加载程序 php-7.3

评论

0赞 Nigel Ren 5/26/2020
您能否显示哪些位有效,哪些无效,如果您遇到任何错误,请包括实际的错误文本。
0赞 Chris Haas 5/26/2020
您是在没有命名空间指令的情况下声明的,然后用命名空间指令调用它?Class_1
0赞 Toolbox 5/26/2020
在问题中添加了一些说明,并更正了命名空间的即时化。
0赞 Dave 5/27/2020
如果在创建类 2 的实例时删除前导反斜杠,会发生什么情况(即:new Area_2\Class_2(););
0赞 Toolbox 5/27/2020
@Dave 同样的错误。似乎前导反斜杠是可选的,所以如果你一开始就有它,PHP就会删除它。这就是为什么错误显示时没有前导反斜杠的原因。

答:

1赞 Chris Haas 5/27/2020 #1

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

执行此操作时:

file_exists($dir . $class_name . $extension)

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

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