我有一个目录将保留所有“帮助程序”类和函数。让我们将目录称为 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