composer.json 必须包含 name、type、autoload 三个字段:name 格式为 vendor/name;type 常用 library/project/metapackage;autoload 至少配置 psr-4(末尾需双反斜杠)或 classmap,避免混用导致僵尸路径。

composer.json 必须有的三个字段
缺了 name、type、autoload 中任意一个,某些场景下会直接失效——比如你写了个私有包但没设 name,packagist 不认;没设 type(哪怕只是 "type": "library"),某些工具链会跳过自动加载注册;而 autoload 为空或缺失,composer dump-autoload 后压根不会生成映射。
实操建议:
-
name格式必须是vendor/name(如"myorg/my-utils"),不能带空格、下划线开头、或只用单段 -
type别乱填,常见值只有library、project、metapackage,填错会导致require-dev行为异常 -
autoload至少配一种方式:"psr-4"最常用,但注意末尾必须带\(如"MyOrg\\": "src/"),漏掉反斜杠会导致类找不到
autoload 的 psr-4 和 classmap 混用陷阱
很多人想“既用 PSR-4 自动发现,又手动加几个老文件”,就同时写 psr-4 和 classmap。问题在于:classmap 生成后是静态路径列表,一旦源文件移动或删了,composer dump-autoload 不会自动清理旧条目,运行时可能报 Class not found 却提示错误行在已删除的文件里。
实操建议:
- 新项目统一用
psr-4,别掺 classmap - 遗留代码必须用 classmap 时,每次增删文件后手动跑
composer dump-autoload -o,且定期检查vendor/composer/autoload_classmap.php里有没有僵尸路径 -
files数组适合放全局函数文件,但它会在每次请求时无条件 require,别往里塞大文件或有副作用的初始化逻辑
require 和 require-dev 的版本约束怎么写才不翻车
写成 "monolog/monolog": "2.0.0" 看似精确,实则危险:Composer 默认启用了稳定性标志,2.0.0 被视为 stable,但如果你本地 minimum-stability 是 dev,反而可能装到 dev 分支;更常见的是写 "^1.2" 却忘了 ^ 对 0.x 版本无效(^0.3.0 只允许 0.3.*,不升级到 0.4)。
实操建议:
- 业务项目优先用
"~2.8"或"^2.8",明确接受小版本更新,避免锁死 - 库项目若依赖不稳定的扩展,显式加
@dev后缀(如"phpunit/phpunit": "9.5.*@dev"),否则 Composer 会因 stability 设置跳过 - 永远在
composer.json顶层设"minimum-stability": "stable",除非你清楚自己在干什么
scripts 里执行命令的路径和环境容易被忽略
scripts 中定义的命令(如 "post-install-cmd")默认在项目根目录执行,但如果你的脚本里写了 cd src && php test.php,它实际工作路径仍是项目根——cd 只对当前 shell 生效,不会改变后续命令的上下文。更隐蔽的是,scripts 不继承 shell 的 $PATH,所以直接写 "phpcs" 很可能报 command not found。
实操建议:
- 脚本中所有路径用绝对路径或
${PWD}开头,例如"php ${PWD}/bin/test.php" - 调用第三方工具时,优先用 vendor bin 路径:
"./vendor/bin/phpcs",而不是假设全局已安装 - 需要环境变量时,不要依赖 .env 文件,scripts 不自动加载它;改用
"APP_ENV=prod php artisan optimize"这种内联写法
最常被漏掉的是 autoload-dev —— 单元测试类如果不在里面声明,composer install --no-dev 后连 phpunit 都找不到测试文件。这问题上线前才暴露,查起来特别费时间。










