繁体   English   中英

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

[英]PHP Autoload Classes Is Not Working With Namespaces

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

我得到的错误是:

警告:require_once(src/test\StringHelper.php):无法打开 stream:没有这样的文件或目录

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。

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

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

在自动加载 function 的上下文中:

spl_autoload_register(function($classname){

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

让我们更进一步,利用自动加载 function 始终接收限定命名空间而不是相对命名空间这一事实:

<?php

namespace Acme;

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

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

例如,在我们的某个项目中给定这两个类......

<?php

namespace Acme;

class Foo {}

Foo.php

<?php

namespace Acme\Bar;

class Bar {}

酒吧.php

...在此文件系统布局中...

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

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

<?php

namespace Acme;

const LIBRARY_DIR = __DIR__.'/lib'; // Where our classes reside

/**
 * Autoload classes within the current namespace
 */
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 的自动加载规范:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM