我有一个目录将保留所有“帮助程序”类和函数。让我们将目录称为 helpers

我想将PSR-4后备目录配置为指向此帮助程序目录:

    "autoload": {
          "psr-4": {
                "": "helpers/"
           }
     }

从Composer文档中:



因此,我的理解是,如果该目录中的文件/类具有符合PSR-4的名称,则我的应用程序应该可以在其中找到它们。

现在,我使用类和Logger 创建了一个文件 helpers/Logger.php

为了1)符合PSR-4和2)正常工作,该类应该使用什么 namespace ?

我试过了
namespace Logger;

并加载类为
$logger = new Logger();

但我收到未找到错误的类记录器

深入研究作曲者代码(loadClass()方法)后,我发现它实际上找到并包含了文件 helpers/Logger.php ,但由于某种原因仍然找不到该类。

根据PSR-4命名空间应该是这样的:
namespace Helpers;

并且类应该这样调用:
$logger = new Helpers\Logger();

我没有找到Class Helpers\Logger,但是除此之外,甚至不包括 helpers/Logger.php 文件。

Composer的 loadClass()方法中用于回退的逻辑如下:
    // PSR-4 lookup
    $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

   ........

    // PSR-4 fallback dirs
    foreach ($this->fallbackDirsPsr4 as $dir) {
        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
            return $file;
        }
    }

因此,它实际上尝试将文件名与完全限定的类名进行匹配。

因此,在我对PSR-4的理解中似乎缺少了一些东西。

但是到底是什么呢?

编辑

为了检查所有内容,我从项目根目录运行了一个简单文件,所有通过composer配置的其他库均已正确加载(例如,Pimple运行正常):
<?php

require_once __DIR__ . '/vendor/autoload.php';
$app = new \Pimple\Container();

/** Register logger */
$app['logger'] = function ($c) {
    return new Helpers\Logger();
};

$app['logger']->info('test');

最佳答案

此后备作为全局 namespace 的目录定义。所以可以,它可以用于自动加载任何 namespace 中的任何类,但是您仍然需要遵循PSR-4规则。目录结构应表示 namespace 结构。如果您有以下规则:

"autoload": {
      "psr-4": {
            "": "helpers/"
       }
 }

您的Helpers\Logger类应该位于helpers/Helpers/Logger.php中,因为Composer将通过这种方式从自动加载规则中解析类文件路径。
helpers/Helpers/Logger.php
   ^       ^      ^
   |       |      |
   |       |    Class name part
   |       |
   |     Namespace part
   |
 Static prefix for global namespace

09-11 01:27
查看更多