Composer禁止在同一个autoload块中混合PSR-0和PSR-4,因二者互斥处理:PSR-4存在时PSR-0被完全忽略;共存需物理隔离,用classmap或files加载遗留代码,PSR-4专管新代码。

Composer 不允许在同一个 autoload 块中混合使用 PSR-0 和 PSR-4 —— 这不是配置技巧问题,而是明确禁止的行为。你写进去,它就静默忽略 PSR-0,只生效 PSR-4,还可能报弃用警告。
为什么 psr-0 和 psr-4 不能共存于同一 autoload 块
Composer 在解析 autoload 时,对 PSR-0 和 PSR-4 是互斥处理的:一旦发现 psr-4 键存在,整个 psr-0 块会被跳过(即使路径不同、命名空间不重叠)。这不是 bug,是 PHP-FIG 和 Composer 团队为消除歧义做的强制约束。
- PSR-0 已在 2014 年被正式弃用,Composer 自 2.0 起仅保留兼容性解析,不参与实际加载流程
- 即使你手动保留
"psr-0": { "Legacy\": "src/legacy/" },只要psr-4存在,这行就完全无效 - 错误现象:类文件明明在
src/legacy/Legacy/Class.php,但new LegacyClass()报Class not found—— 因为 PSR-4 规则已拦截并尝试去src/Legacy/Class.php找(按前缀匹配),而那里没有
如何让旧 PSR-0 类和新 PSR-4 类共存
必须把两类逻辑物理隔离,用不同 autoload 类型承载,而非“混配”。核心思路是:PSR-4 管新代码,classmap 或 files 管遗留结构。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 把所有 PSR-0 风格的类(比如含下划线的类名、非标准目录嵌套)统一放进一个目录,如
legacy/ - 在
composer.json中用classmap加载它:"classmap": ["legacy/"]—— 这会扫描生成静态映射,不依赖命名规则 - 如果只有几个关键函数或工具类,改用
files:"files": ["legacy/helpers.php"],每次请求都 require - 绝对不要写
"Legacy\": "legacy/"同时出现在psr-0和psr-4下——哪怕路径不同,只要命名空间前缀一致,PSR-4 就会接管全部查找
psr-4 多命名空间配置时的常见翻车点
你以为加了多个 PSR-4 就能覆盖所有场景,但实际加载行为取决于前缀长度和路径拼接逻辑,稍不注意就会“找错地方”。
-
"App": "src/"和"App\Controller": "old-controllers/"共存是危险的:类AppControllerFoo可能被匹配到前者(去src/Controller/Foo.php)或后者(去old-controllers/Foo.php),取决于你是否真在src/下建了Controller/目录 - 正确做法是前缀互斥:
"OldApp\": "old-controllers/",避免任何包含关系 - 路径结尾必须带斜杠:
"src/"✅,"src"❌(旧版 Composer 会 warning,新版可能直接失效) - 修改完
composer.json后,必须运行composer dump-autoload -o,否则 vendor/autoload.php 不更新,一切配置等于没写
最易被忽略的是 classmap 的优先级 —— 它排在 PSR-4 之后,但一旦命中就立即加载,不回退。所以当 PSR-4 找不到类时,classmap 才有机会介入。这意味着,如果你把 legacy 类放在 classmap 里,它不会干扰新 PSR-4 逻辑;但如果你误把新类也塞进 classmap,反而会绕过 PSR-4 的路径校验,埋下维护隐患。

















