PHP自动加载类与命名空间不起作用

12 浏览
0 Comments

PHP自动加载类与命名空间不起作用

我试过写下面的代码,但无法弄清楚为什么在spl_autoload_register()中无法找到带有命名空间的类?

我收到的错误是:

警告:require_once(src/test\StringHelper.php):无法打开

流:没有这样的文件或目录

Autoloader.php 文件:

hello() . PHP_EOL; // 返回文本

src 文件夹中的 StringHelper.php 文件:


我也使用的是XAMPP,如果有差异的话。

0
0 Comments

PHP Autoload Classes Is Not Working With Namespaces

问题:

当使用命名空间时,PHP自动加载类功能无法正常工作。

原因:

问题出现的原因是在自动加载函数中,需要将类名转换为只保留类名,去掉命名空间部分。可以使用substr和strrpos函数来实现这个转换。

解决方法:

在自动加载函数中添加以下代码:

spl_autoload_register(function($classname){
    $classname = substr($classname, strrpos($classname, "\\") + 1);
    require_once "src/{$classname}.php"; 
});

进一步改进的方法是利用自动加载函数始终接收完整的命名空间,而不是相对命名空间。可以根据命名空间和子命名空间将其映射到文件系统路径中。

例如,有以下两个类:

namespace Acme;
class Foo {}

namespace Acme\Bar;
class Bar {}

在文件系统中的布局如下:

my-project
`-- library
    `-- Acme
        |-- Bar
        |   `-- Bar.php
        `-- Foo.php

可以通过以下方式实现命名空间类和物理位置之间的简单映射:

namespace Acme;
const LIBRARY_DIR = __DIR__.'/lib'; // Where our classes reside
spl_autoload_register(function($qualified_class_name) {
    $filepath = str_replace(
        '\\', // Replace all namespace separators...
        '/',  // ...with their file system equivalents
        LIBRARY_DIR."/{$qualified_class_name}.php"
    );
    if (is_file($filepath)) {
        require_once $filepath;
    }
});
new Foo();
new Bar\Bar();

注意,可以注册多个自动加载函数来处理不同物理位置中的不同顶级命名空间。在实际项目中,建议熟悉Composer的自动加载机制。

此外,还可以查看PHP的自动加载规范(PSR-4)来了解更多信息。

参考链接:

- Composer autoloading mechanism: [https://getcomposer.org/doc/01-basic-usage.md#autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading)

- PHP autoloading specification (PSR-4): [https://www.php-fig.org/psr/psr-4/](https://www.php-fig.org/psr/psr-4/)

0