微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PHP 自动加载类不适用于命名空间

如何解决PHP 自动加载类不适用于命名空间

我已尝试编写以下代码,但无法弄清楚为什么在具有命名空间的 spl_autoload_register() 中找不到该类?

我得到的错误是:

警告:require_once(src/test\StringHelper.PHP):打开失败 流:没有那个文件或目录

Autoloader.PHP 文件

<?PHP

spl_autoload_register(function($classname){
    require_once "src/$classname.PHP"; // NOT WORKING DYNAMICALLY

//    require_once "src/StringHelper.PHP"; // WORKING WHEN HARD CODED
});

$stringHelper1 = new test\StringHelper(); // Class with namespace defined
echo $stringHelper1->hello() . PHP_EOL; // returns text

src 文件夹中的 StringHelper.PHP

<?PHP namespace test;

class StringHelper{

    function hello(){
        echo "hello from string helper";
    }
}

如果这有所作为,我也会使用 XAMPP。

解决方法

正如评论中已经指出的,您需要删除除类名之外的所有内容,如下所示:

$classname = substr($classname,strrpos($classname,"\\") + 1);

在自动加载功能的上下文中:

spl_autoload_register(function($classname){

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

让我们更进一步,利用自动加载函数总是接收限定命名空间而不是例如相对命名空间这一事实:

<?php

namespace Acme;

$foo = new \Acme\Foo(); // Fully qualified namespace 
$foo = new Acme\Foo();  // Qualified namespace
$foo = new Foo();       // Relative namespace

在所有三个实例中,我们的自动加载函数总是以 Acme\Foo 作为参数。考虑到这一点,实现将命名空间和任何子命名空间映射到文件系统路径的自动加载器策略是相当容易的 - 特别是如果我们在文件系统层次结构。

例如,鉴于我们的某个项目中的这两个类...

Acme

Foo.php

<?php

namespace Acme;

class Foo {}

Bar.php

...在这个文件系统布局中...

<?php

namespace Acme\Bar;

class Bar {}

...我们可以实现命名空间类与其物理位置之间的简单映射,如下所示:

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

另请注意,您可以注册多个自动加载函数,例如,处理不同物理位置的不同顶级命名空间。不过,在实际项目中,您可能想要熟悉 Composer 的自动加载机制:

在某些时候,您可能还想查看 PHP 的自动加载规范:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。