不能设 cron 每周自动 composer update,因其依赖解析非幂等:同一 composer.json 在不同时间执行结果可能因上游版本发布、移除或仓库异常而生成不同 composer.lock,导致不可控变更和运行时故障。

composer update 不该定期自动跑,也不该按“周期”执行——它本质是一次性、有明确意图的变更操作,不是定时任务。
为什么不能设 cron 每周自动 composer update
Composer 的依赖解析不是幂等过程:同一份 composer.json 在不同时间跑 composer update,可能因上游包发布新版本、移除旧版本或仓库临时不可用,得到完全不同的 composer.lock。这不是“更新”,是“重算”,结果不可控。
- 某天
guzzlehttp/guzzle发布7.9.0,含一个未文档化的 API 微调,你的 HTTP 客户端突然抛InvalidArgumentException -
monolog/monolog的^2.10范围内新增了3.0.0-RC1,而 Composer 2.5+ 默认 prefer-stable 为 true,但若对方包没设"minimum-stability": "stable",仍可能意外拉入 RC 版本 - CI 流水线里
composer update成功,但本地composer install失败,报错The requested package ... could not be found—— 因为 lock 文件里记录的某个子依赖 hash 已被 Packagist 清理(常见于 dev 分支快照)
真正需要“周期性检查”的是 composer outdated
composer outdated 是只读命令,不修改任何文件,只比对当前 composer.lock 和远程仓库最新可用版本,适合放进 CI 或每日脚本。
- 加
--direct只看require和require-dev顶层声明的包,避免被几十个间接依赖刷屏 - 加
--minor-only过滤掉主版本升级(如^2.0 → ^3.0),这类变更需人工评估 - 加
--format=json方便下游工具解析,比如发 Slack 告警或写入日志文件 - 别信
composer outdated --all:它会列出所有传递依赖,其中 80% 你根本无法直接控制,徒增噪音
日志追溯靠的是 git commit + composer.lock 变更,不是命令历史
想查“上周五谁升了 symfony/console”,翻 ~/.bash_history 没用——那个记录早被覆盖,且不含上下文。真正可追溯的是 Git 提交本身。
立即学习“PHP免费学习笔记(深入)”;
- 每次
composer update后必须git add composer.lock && git commit -m"chore(deps): update symfony/console from 6.4.3 to 6.4.5" - 提交信息里写明变更范围(如只升一个包)和理由(如“修复 CVE-2026-1234”),不要用
update deps这种模糊描述 - CI 流水线中加检查:
git diff --quiet HEAD^1 composer.lock || echo "lock file changed — verify update intent",防止误提交 - 如果团队用 GitHub/GitLab,开启 protected branches + require status checks,强制
composer validate和composer diagnose通过才允许合并
生产环境部署永远只走 composer install
CI 构建镜像或部署到服务器时,composer install 是唯一合法命令。它跳过依赖解析,只按 composer.lock 精确还原,这是稳定性的底线。
- 线上机器禁止装
composer—— 部署包应包含已安装好的vendor/,或使用composer install --no-dev --optimize-autoloader --no-interaction一次性完成 - 若发现线上行为异常,第一反应不是“是不是该更新”,而是
git blame composer.lock查最近一次锁文件变更,再顺藤摸瓜看对应 commit 的改动说明 -
composer install报错Your lock file does not contain a compatible set of packages?说明composer.json和composer.lock已脱节,此时不是升级,而是先git checkout -- composer.lock回退,再排查谁改了 json 却没跑 update
依赖更新不是维护,是重构;日志追溯不是查命令,是读 Git 提交。把 composer.lock 当作源码的一部分来对待,比任何周期计划都管用。



















