Composer 2.0+ 彻底移除 PSR-0 支持,硬配 "psr-0" 字段被静默忽略;唯一可靠补救是手动注册 spl_autoload_register 实现下划线转路径逻辑,或改用 classmap 映射。

Composer 2.0+ 已彻底移除 PSR-0 自动加载支持,composer dump-autoload 不会生成任何 PSR-0 映射,硬配 "psr-0" 字段也无效——这不是配置问题,是能力缺失。
为什么 PSR-0 配置在 composer.json 里完全没用
PSR-0 是 Composer 1.x 的遗留机制,2.0 起被主动删除。即使你在 composer.json 中写入:
{
"autoload": {
"psr-0": { "Swift_": "vendor/swiftmailer/swiftmailer/lib/classes/" }
}
}
运行 composer dump-autoload 后,vendor/composer/autoload_psr0.php 文件根本不会生成,vendor/autoload.php 也不会包含任何 PSR-0 逻辑。
- Composer 不再解析
"psr-0"字段,连 warning 都不报,静默忽略 - 旧类库(如
swiftmailer/swiftmailer:v5.4、pear/console_table)的类名含下划线(Swift_Mime_SimpleMessage),路径需转为swift/mime/simplemessage.php,这种转换逻辑已从自动加载器中剥离 - 降级 Composer 或找“PSR-0 兼容插件”属于高风险操作:破坏依赖一致性,且多数插件未适配 PHP 8.2+ 和 Composer 2.5+
手动注册 PSR-0 加载器(运行时补救)
唯一可靠方式是在项目入口(如 index.php 或 bootstrap.php)中,引入 vendor/autoload.php 后,用 spl_autoload_register() 补上规则。
- 必须严格实现 PSR-0 转换:下划线
_→ 目录分隔符/,整个类名转小写,末尾加.php - 必须检查
class_exists($class, false)和interface_exists($class, false),避免重复加载 - 路径拼接要精准——不能写死
vendor/xxx/lib/,得用__DIR__ . '/vendor/...'或读取composer.json中的实际安装路径 - 示例片段(适配
Swift_前缀):
require_once __DIR__ . '/vendor/autoload.php';
spl_autoload_register(function ($class) {
if (false === strpos($class, '_') || class_exists($class, false) || interface_exists($class, false)) {
return;
}
$file = __DIR__ . '/vendor/swiftmailer/swiftmailer/lib/classes/'
. str_replace('_', '/', strtolower($class)) . '.php';
if (is_file($file)) {
require_once $file;
}
});
改用 classmap 是更稳的选择(推荐用于少量类)
如果旧类库只有几个核心类(比如 Console_Table、DB、HTTP_Request),直接走 classmap 比手写 autoload 更轻量、更可控。
- 在
composer.json中添加:
{
"autoload": {
"classmap": ["vendor/pear/console_table/", "vendor/pear/http_request/"]
}
}
- 执行
composer dump-autoload,Composer 会扫描目录下所有.php文件,提取class、interface、trait声明并生成静态映射 - classmap 不依赖命名空间或文件名格式,哪怕
db.php里定义了Database类,也能正确加载 - 缺点:新增类后必须重跑
dump-autoload;不适用于动态生成类名的场景(如eval()或魔术方法)
真正容易被忽略的是:PSR-0 不是“兼容模式”,而是已被移除的协议;你不是在调试配置,而是在绕过一个不存在的机制。选 spl_autoload_register 就得自己担起路径转换和存在性检查,选 classmap 就得接受手动刷新的约束——没有银弹,只有权衡。










