安全升级必须从composer outdated --direct开始,它只检查显式声明的包,明确标识安全更新、主版本跃迁及检测失败原因;CI中应每日执行--minor-only筛选小版本更新,所有composer update操作须指定包名与约束,严禁裸命令或生产环境定时自动更新。

别用 composer update 直接跑,也别设 crontab 自动更新生产环境——这两条是翻车最频繁的起点。
怎么安全地发现该不该升级
所有升级动作必须从 composer outdated --direct 开始。它只看你在 composer.json 里显式写的包,排除传递依赖干扰,能立刻告诉你三件事:
- 哪些包有安全更新(标
security) - 哪些已跳主版本(比如
monolog/monolog显示v1.27.1 → v3.5.0) - 哪些根本没被检测到(常因
replace或require-dev中的冲突约束)
如果 outdated 没输出,先检查 composer.json 是否设了 "minimum-stability": "stable" 和 "prefer-stable": true——这会过滤掉所有预发布版候选,临时删掉再试一次。
CI 中建议每日跑 composer outdated --minor-only,避开 major 跳变,只盯小修小补。
怎么精确控制升级范围
composer update 默认不是“升级”,而是丢掉 composer.lock、重算整棵依赖树——哪怕只升一个补丁号,也可能触发底层行为变更(如 Guzzle 的超时逻辑收紧、Monolog 的日志字段名改写)。
必须指定包名和约束:
- 单个包:
composer update guzzlehttp/guzzle:^7.5(别漏^或~) - 一组相关包:
composer update laravel/framework illuminate/*(引号防 shell 展开) - 连带直接依赖:
composer update monolog/monolog --with-dependencies(避免子依赖卡旧版) - 递归更新整个子图:
composer update monolog/monolog --with-all-dependencies(慎用,易冲突)
永远不要在部署脚本或 crontab 里写裸 composer update。真要定时,只限 require-dev 工具包,且必须加 --dry-run 验证。
为什么 composer.lock 不能删、不能忽略
composer.lock 不是缓存,是契约文件。它记录每个包的 exact commit hash、PHP 扩展要求、甚至安装时的平台配置(config.platform)。删了重生成,等于放弃对依赖一致性的控制。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
常见错误:
- CI 中用
composer install却没提交composer.lock→ 构建拉到的版本每次不同 - 本地改完
composer.json忘了update→install仍按旧 lock 装,新约束不生效 - PHP 版本升级后没删
composer.lock→install失败或装错兼容版
生产部署只允许 composer install;本地升级后,composer.lock 必须和 composer.json 一起提交。
crontab 定时更新只适用于开发工具包
系统级定时任务不能直接写 composer update,因为 crontab 默认工作目录是用户家目录,找不到 composer.json。
正确写法(Linux/macOS):
cd /path/to/project && composer update --no-interaction --dry-run > /var/log/composer-weekly.log 2>&1
确认无冲突后,删掉 --dry-run 再启用。只更新 require-dev 类包(如 phpunit/phpunit、phpstan/phpstan),绝不碰运行时依赖。
更推荐的做法是:用 GitHub Actions 触发 PR,自动跑 outdated + update + 测试 + 提交 lock,失败可追溯、变更可审查——比服务器上半夜自己瞎跑靠谱得多。
真正难的不是命令怎么敲,而是判断哪个包该升、升到哪版、谁会拦路、升完怎么验证。这些没法靠定时脚本兜底,得靠 why-not、show -l、dump-autoload -o 和最小闭环测试串起来。

















