使用命名空间自动加载

时间:2017-12-28 15:57:08

标签: php

我的结构:

/test/init.php
/test/sub/Info.php

的init.php:

<?php

namespace test;

$namespaces = function($path) {
    //echo $path; = test\sub\Info
    if (preg_match('/\\\\/', $path)) {
        $path = str_replace('\\', DIRECTORY_SEPARATOR, $path);
    }
    //echo $path; = test\sub\Info
    if (file_exists("{$path}.php")) {
        require_once("{$path}.php");
    }
};

spl_autoload_register($namespaces);

$info = new sub\Info();

和Info.php:

<?php

namespace test\sub;

class Info
{
    public function __construct()
    {
        echo 123;
    }
}

为什么这不起作用?

我使用Windows,为什么DIRECTORY_SEPARATOR == \?

编辑: 对不起,我更新了我的问题。我忘了在stackoverflow上粘贴spl_autoload_register。

2 个答案:

答案 0 :(得分:1)

理想情况下,您的自动加载器需要在目录结构的顶级命名空间之外定义 - 此时您已设置它的方式,它试图从内部包含文件test/sub/Info.php测试目录,而不是从根(即test/test/sub/Info.php,它不存在)

如果从两个文件中删除命名空间前缀test(因此将其从init.php完全删除,并在namespace sub;中只有sub/Info.php),那么它将正常工作。另一种选择是将自动加载器移动到根目录中的文件中,以便命名空间再次与文件系统布局匹配。

答案 1 :(得分:0)

您正在使用相对路径,因此有几件事情可能出错......您可以通过以下方式查看当前工作目录:

echo getcwd();

你也可以尝试这样的事情:

$namespaces = function($class) {
    $basepath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR;
    $file = $basepath . str_replace('\\', DIRECTORY_SEPARATOR, $class) . ".php";

    if (!file_exists($file) || !is_readable($file)) {
        return false;
    }

    require_once($file);

    return class_exists($class, false);
};

变量$basepath也可以是已定义的常量,也可以是配置文件中的变量......