提问人:Toolbox 提问时间:5/26/2020 最后编辑:Toolbox 更新时间:5/27/2020 访问量:147
不能将命名空间与自动加载器一起使用
Cannot use namespace with autoloader
问:
使用自动加载器“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";
}
}
答:
1赞
Chris Haas
5/27/2020
#1
对于使用命名空间的任何类,自动加载器假定使用基于目录的系统,即使它不是预期的。原因是命名空间分隔符与目录分隔符相同(或足够相似,以至于系统会自动在两者之间进行转换)。
执行此操作时:
file_exists($dir . $class_name . $extension)
使用类 ,PHP 将其转换为 。Area_2\Class_2
./Area_2\Class_2.class.php
因此,您的代码需要文件夹。
评论
Class_1
new Area_2\Class_2();
);