composer.json 是项目依赖契约,require 放运行时必需包,require-dev 放开发期工具;autoload 需匹配命名空间与路径;minimum-stability 和 prefer-stable 控制版本稳定性;scripts 仅作命令别名,部署逻辑应独立;config.platform 用于模拟目标环境。

Composer.json 不是配置清单,而是项目依赖契约——写错一个字段,composer install 就可能装出完全不同的包版本,甚至根本跑不起来。
require 和 require-dev 到底该放什么
这两个字段决定哪些包会被安装(以及是否进生产环境)。很多人把测试工具、代码生成器也塞进 require,结果上线后多装一堆没用的包,还可能引入安全风险。
-
require只放运行时真正需要的包,比如"monolog/monolog": "^2.0"—— 没它,日志就打不出去 -
require-dev放开发期才用的,比如"phpunit/phpunit": "^9.5"或"friendsofphp/php-cs-fixer": "^3.0" - 如果用了
composer install --no-dev部署,require-dev里的东西压根不会装,所以别指望它们在生产环境起作用 - 注意:某些包(如
symfony/console)在开发和运行时都可能用到,得看你的实际调用路径——不是“带 console 字样”就一定放require
autoload 自动加载怎么配才不报 Class not found
写完类文件却提示 Class 'AppHttpController' not found?大概率是 autoload 没对上真实目录结构或命名空间。
-
"psr-4": {"App\": "src/"}要求src/Http/Controller.php里必须声明namespace AppHttp;,少一个反斜杠或大小写错(appvsApp)都会失败 -
"classmap": ["lib/", "scripts/"]是兜底方案,适合老项目或无命名空间的类,但每次增删文件后要手动跑composer dump-autoload - 别混用
psr-4和psr-0;PHP 7.4+ 项目基本只用psr-4 - 改完 autoload 一定要执行
composer dump-autoload,否则缓存还是旧的
minimum-stability 和 prefer-stable 怎么配合用
默认情况下,composer require some/package 可能装个 v3.0.0-beta2,上线前才发现有严重 bug。这不是运气差,是稳定性策略没设好。
-
"minimum-stability": "stable"是底线,表示除非显式指定,否则绝不装beta、dev、alpha版本 -
"prefer-stable": true是保险绳:即使某包最新版是dev-master,也会优先选最近的stable版(比如2.8.1) - 想临时装一个不稳定版?写成
"some/package": "dev-main as 1.0.0"或"dev-develop#abc123",但别长期留着 - 注意:
minimum-stability是全局开关,require里某条的版本约束(如"^2.0@dev")可以覆盖它——这是隐患点,搜@符号就能发现这种“悄悄开后门”的写法
scripts 字段不是用来写部署脚本的
看到别人在 scripts 里写 "post-install-cmd": "sh deploy.sh",就以为这是 Composer 的“钩子系统”?其实它只是命令别名,没权限、没上下文、不保证执行顺序。
-
scripts最靠谱的用途是开发辅助:比如"cs-fix": "php-cs-fixer fix",然后用composer cs-fix呼起 -
post-autoload-dump可以触发自动注册事件类,但别在里面做耗时操作(比如拉 Git、解压文件),会拖慢composer install - 部署逻辑必须抽离到独立脚本(如
bin/deploy),scripts顶多调用一次"deploy": "bash bin/deploy" - 所有
scripts默认在项目根目录执行,__DIR__在 PHP 脚本里拿到的是 vendor 目录,不是你想象的项目路径
最常被忽略的其实是 config.platform —— 它假装当前环境是某个 PHP 版本或扩展存在,影响依赖解析结果。本地 PHP 8.2,但服务器只有 8.0?不配这个,composer install 可能给你装个要求 ext-gmp 的包,而线上根本没这个扩展。










