PSR-0 已被 Composer 彻底弃用,新项目必须使用 PSR-4;常见错误“A non-empty PSR-4 prefix must end with a namespace separator”源于 psr-4 配置中命名空间前缀未以双反斜杠(\)结尾,导致解析失败。

PSR-0 已被 Composer 彻底弃用,新项目必须用 PSR-4;你遇到的 [InvalidArgumentException] A non-empty PSR-4 prefix must end with a namespace separator 错误,不是 PSR-0 的问题,而是 PSR-4 配置写错了。
PSR-4 命名空间前缀必须以 \ 结尾
Composer 解析 composer.json 中的 psr-4 配置时,要求每个命名空间前缀(如 "App\")在 JSON 字符串中显式以双反斜杠结尾——实际含义是单个反斜杠(),即命名空间分隔符。漏掉这个结尾会直接报错。
-
"App": "src/"→ 报错:[InvalidArgumentException] A non-empty PSR-4 prefix must end with a namespace separator -
"App\": "src/"→ 正确(JSON 中写双反斜杠,解析为App) -
"App\Controllers\": "src/Controllers/"→ 也合法,但不推荐:前缀越长,可映射的子命名空间越少,灵活性下降
PSR-4 不处理下划线,PSR-0 会把下划线转成目录分隔符
类名里有下划线,在 PSR-0 下会被当作路径分隔符处理;PSR-4 完全忽略下划线,只认反斜杠。
-
use AppModelsUser_Settings;→ PSR-0 会尝试加载src/App/Models/User/Settings.php,PSR-4 则只找src/Models/User_Settings.php - 这意味着:如果你从 PSR-0 迁移到 PSR-4,又保留了带下划线的类名,文件位置必须重排,否则
Class not found - 现代 PHP 项目基本不用下划线命名类,所以 PSR-4 的行为更符合直觉和 PSR-1 规范
PSR-4 路径映射比 PSR-0 少一层目录
这是最影响目录结构的实际区别。PSR-4 剥离前缀后直接映射剩余命名空间段;PSR-0 把整个命名空间(含前缀)都塞进路径。
- 配置
"App\": "src/",使用AppControllersHome: - PSR-4 →
src/Controllers/Home.php - PSR-0 →
src/App/Controllers/Home.php(多出App/目录) - 这种冗余嵌套让 PSR-0 在重构命名空间或迁移包时非常脆弱,也是它被淘汰的核心原因
混用或残留 psr-0 配置会触发警告甚至失败
Composer 1.0+ 对 psr-0 配置块仅做兼容性保留,但每次运行 composer install 或 composer dump-autoload 都会输出弃用警告;未来版本将直接拒绝加载。
- 检查
composer.json是否还存在"psr-0"字段,哪怕值为空也要删掉 -
"autoload"下同时存在psr-0和psr-4,Composer 会优先用 PSR-4,但psr-0块仍会触发警告 - 旧项目升级时,别只改配置——还要按 PSR-4 规则调整文件位置,否则自动加载会静默失败
最容易被忽略的是:错误信息里提到 PSR-4 前缀必须以反斜杠结尾,但很多人第一反应是去查 PSR-0 文档,结果越查越偏。其实只要盯住 composer.json 里的 psr-4 块,逐个检查结尾、路径是否存在、类文件名是否与类名大小写完全一致,90% 的问题就解决了。











