如何正确使用 composer psr-4 fallback
How to use composer psr-4 fallback correctly
我有一个目录将保留所有 "helper" classes 和函数。让我们调用目录 helpers.
我想配置 PSR-4 回退目录指向这个 helpers 目录:
"autoload": {
"psr-4": {
"": "helpers/"
}
}
来自 Composer 文档:
... fallback directory where any namespace will be looked for.
所以我的理解是,如果我在该目录中的 files/classes 具有符合 PSR-4 的名称,我的应用程序应该能够在那里找到它们。
现在我用 class Logger[= 创建了一个文件 helpers/Logger.php 18=]
为了 1) 符合 PSR-4 和 2) 正常工作,这个 class 应该使用什么命名空间?
我试过了
namespace Logger;
并将 class 加载为
$logger = new Logger();
但我收到错误 Class 未找到记录器
深入研究作曲家代码(loadClass() 方法)告诉我它实际上找到并包含了文件 helpers/Logger.php,但由于某种原因仍然找不到 class。
根据 PSR-4 命名空间应该是这样的:
namespace Helpers;
而class应该这样称呼:
$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;
}
}
因此它实际上尝试将文件名与完全限定的 class 名称相匹配。
所以我对 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');
PSR4 区分大小写,因此如果您将 class 放在文件夹 helpers
中并且 class 本身使用命名空间 Helpers
,则不会不工作。
此后备作为全局命名空间的目录定义。所以是的,它可以用于自动加载任何命名空间中的任何 class,但你仍然需要为它们遵循 PSR-4 规则。目录结构应该代表命名空间结构。如果你有这样的规则:
"autoload": {
"psr-4": {
"": "helpers/"
}
}
你的 Helpers\Logger
class 应该在 helpers/Helpers/Logger.php
中,因为这样 Composer 将从自动加载规则中解析 class 文件路径。
helpers/Helpers/Logger.php
^ ^ ^
| | |
| | Class name part
| |
| Namespace part
|
Static prefix for global namespace
我有一个目录将保留所有 "helper" classes 和函数。让我们调用目录 helpers.
我想配置 PSR-4 回退目录指向这个 helpers 目录:
"autoload": {
"psr-4": {
"": "helpers/"
}
}
来自 Composer 文档:
... fallback directory where any namespace will be looked for.
所以我的理解是,如果我在该目录中的 files/classes 具有符合 PSR-4 的名称,我的应用程序应该能够在那里找到它们。
现在我用 class Logger[= 创建了一个文件 helpers/Logger.php 18=]
为了 1) 符合 PSR-4 和 2) 正常工作,这个 class 应该使用什么命名空间?
我试过了
namespace Logger;
并将 class 加载为
$logger = new Logger();
但我收到错误 Class 未找到记录器
深入研究作曲家代码(loadClass() 方法)告诉我它实际上找到并包含了文件 helpers/Logger.php,但由于某种原因仍然找不到 class。
根据 PSR-4 命名空间应该是这样的:
namespace Helpers;
而class应该这样称呼:
$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;
}
}
因此它实际上尝试将文件名与完全限定的 class 名称相匹配。
所以我对 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');
PSR4 区分大小写,因此如果您将 class 放在文件夹 helpers
中并且 class 本身使用命名空间 Helpers
,则不会不工作。
此后备作为全局命名空间的目录定义。所以是的,它可以用于自动加载任何命名空间中的任何 class,但你仍然需要为它们遵循 PSR-4 规则。目录结构应该代表命名空间结构。如果你有这样的规则:
"autoload": {
"psr-4": {
"": "helpers/"
}
}
你的 Helpers\Logger
class 应该在 helpers/Helpers/Logger.php
中,因为这样 Composer 将从自动加载规则中解析 class 文件路径。
helpers/Helpers/Logger.php
^ ^ ^
| | |
| | Class name part
| |
| Namespace part
|
Static prefix for global namespace