无法让我的自动加载器使用命名空间

Can't get my autoloader to work with namespaces

我的文件夹结构与我的 PHP 文件及其命名空间有关。

这是我的文件夹结构:

myproject
|
-- entry.php
-- src
    |
    -- IndexController.php

我的 entry.php 看起来像这样:

<?php

spl_autoload_register(function (String $class) {
  $sourcePath = __DIR__ . DIRECTORY_SEPARATOR . 'src';
  $replaceRootPath = str_replace('myproject\Controllers', $sourcePath, $class);
  $replaceDirectorySeparator = str_replace('\', DIRECTORY_SEPARATOR, $replaceRootPath);
  $filePath = $replaceDirectorySeparator . '.php';

  if (file_exists($filePath)) {
    require($filePath);
  }
});

$indexController = new myproject\Controllers\IndexController;
$result = $indexController->controlSomething('this thing');

print($result);

我的 src/IndexController.php 看起来像这样:

<?php

namespace myproject\Controllers;

class IndexController
{
  public function controlSomething(string $something): string {
    return $something;
  }
}

这很好用。但是,我想要一些不同的文件夹结构。我想更深入地放置一个文件夹,以使我的控制器在某个地方井井有条。所以我想要一个 Controllers 文件夹来保存我的控制器。将我的文件夹结构更改为:

myproject
|
-- entry.php
-- src
    |
    -- Controllers
        |
        -- IndexController.php

导致错误 Class 'myproject\Controllers\IndexController' not found

我怎样才能做到这一点?我尝试将 /Controllers 添加到定义路径和命名空间的代码中,但我一直收到此错误。

尝试

<?php

namespace myproject\src\Controllers;

在您当前的设置中,您已将文件夹 src 映射到基本命名空间 myproject\Controllersmyproject\Controllers 之后的任何内容都应反映从 src.

开始的子目录结构

接下来是:当你把IndexController放在目录src\Controllers中时,自动加载器只有在class全名是myproject\Controllers\Controllers\IndexController的情况下才能找到它。

您可能想要做的是直接将 src 映射到 myproject,例如

$replaceRootPath = str_replace('myproject', $sourcePath, $class);

我倾向于使用 php 的当前行业标准的解决方案是使用 composer 作为自动加载器。

安装后,配置自动加载器将变得如此简单 json 段:

"autoload": {
    "psr-4": {
        "myproject\": "src"
    }
},

并且,可选地,

"autoload-dev": {
    "psr-4": {
        "myproject\Test\": "tests"
    }
},

使用 composer 的另一个好处是能够从大量开源模块中提取信息来简化您的生活。