PSR-4映射是静态查表而非运行时推断,Composer将composer.json中psr-4配置解析为vendor/composer/autoload_psr4.php中的PHP数组,加载器仅据此查表定位文件,不扫描目录;命名空间前缀必须以反斜杠结尾,路径拼接时剥离前缀、将替换为/、拼接目录并加.php后缀,三者任一错位即失败;修改配置后必须执行composer dump-autoload更新映射表,否则无效。

直接塞进 src/ 就是自毁式解耦——类加载爆炸、模块间硬依赖、改一行代码要清三处缓存。真能落地的,只有 path 仓库 + 精准 PSR-4 映射 + 接口契约这三板斧。
为什么 composer require 自己的业务模块会炸
业务模块不是工具库,它活在 Laravel/Symfony 的容器里:要调 request()、读 config('app.debug')、发 event(new OrderPlaced)。一旦打成 Packagist 包:
-
IlluminateContractsContainerBindingResolutionException是常态,vendor 里的类根本没注册进主应用容器 - 每次改
./modules/order/src/OrderService.php,都得composer update app/order-module+ 清 config/cache/route 缓存 + 重启队列 -
autoload-dev和主项目 PSR-4 映射重叠,composer dump-autoload后AppModelsUser可能从订单模块里加载出来 - 测试必须启动整个 Web 应用,CI 单次跑完要 3 分钟起步
path 仓库配置不生效的三个硬条件
缺一不可,否则 vendor/myapp/order-module 下不会生成软链接,模块压根不被加载:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
repositories中的url必须指向**含合法composer.json的具体子目录**(如"./modules/order"),不能只写"./modules/*" - 子模块的
composer.json必须有非空name字段,且格式为"myapp/order-module",和根项目require中的包名**完全一致** - 根项目的
require里不能写"myapp/order-module": "^1.0"这类带版本约束的写法——本地path包不走版本解析,必须统一用"*"或"@dev"
PSR-4 映射怎么配才不越界
最常踩的坑是所有模块都写 "App": "src/",结果只有最后一个生效,命名空间彻底乱套:
- 每个模块的 autoload 必须收敛到自身命名空间,比如订单模块写
"MyAppOrder\": "src/",绝不能写"App\": "src/" - 模块内禁止硬编码引用主项目命名空间(如
new AppModelsUser),契约只能通过接口或 DTO 传递 - 模块的
composer.json里不要出现require-dev或测试框架依赖(如phpunit/phpunit),否则会污染主项目vendor/ - 执行
composer update myapp/order-module后,Composer 会在vendor/myapp/order-module创建符号链接,既保持物理隔离,又享受自动加载
真正难的不是配置,而是把“模块间通信必须走接口”这条规则刻进每个 PR 的 Code Review 里——只要漏掉一次 new,后面就再也拆不干净了。

















