composer update 不自动重下 ZIP 是因它优先复用本地缓存(~/.composer/cache/files/)中校验通过的包,核心任务是解析依赖并更新 lock 文件,而非强制刷新。触发重下的三种方式:--no-cache、--refresh(≥2.5)、手动删 ZIP+清 lock。

composer update 本身不会重新下载已缓存的 ZIP 包,除非你明确绕过缓存或强制刷新元数据。 它默认复用 ~/.composer/cache/files/ 里的 ZIP,哪怕远程包已更新、校验和变了,只要没触发重装逻辑,就不会拉新包。
为什么 composer update 不自动重下 ZIP?
因为 composer update 的核心任务是「解析依赖树 + 更新 lock 文件 + 安装满足约束的版本」,不是「清旧装新」。它优先从本地缓存解压,只要:dist.sha256 校验通过、ZIP 文件存在、且版本符合 composer.lock 或求解结果,就跳过网络请求。
- 即使你删了
vendor/,composer update仍会从缓存解压,不发Downloading日志 - 如果缓存 ZIP 损坏(如
Corrupted zip file),它不会自动重试,而是直接报错退出 - 镜像源切换后,旧 ZIP 仍被复用——缓存文件不绑定源地址,只认哈希
真正触发重新下载 ZIP 的三种方式
必须打破「缓存命中」条件,让 Composer 被迫走网络。以下操作均需配合 composer update 使用:
-
composer update --no-cache:跳过所有缓存查找,每个包都重新下载 ZIP。适合调试或 CI 环境,但流量大、耗时长 -
composer update --refresh(Composer ≥ 2.5):强制刷新远程元数据(packages.json等),再做依赖解析。虽不直接删 ZIP,但若新解析出的版本与缓存 ZIP 的dist.sha256不匹配,就会触发重下 - 手动删特定 ZIP + 清
composer.lock:进$(composer config --global cache-dir)/files/,用包名模糊匹配并删除对应 ZIP(如*guzzlehttp*guzzle*.zip),再删composer.lock并运行composer update。这样能精准控制重下范围
常见误操作及后果
很多人以为「清缓存 = 重下包」,其实不然:
-
composer clear-cache后直接composer update:仍可能复用未损坏的旧 ZIP,尤其当composer.lock未变时 - 只删
vendor/不动缓存:Composer 仍从~/.composer/cache/files/解压,速度飞快但内容未必新 - 删了
composer.lock却没清缓存:composer update会生成新 lock,但若缓存里有旧版 ZIP 且哈希匹配,它照样解压旧包,而非拉新版
最稳妥的组合是:删 composer.lock + composer clear-cache + composer update --no-cache。但要注意——--no-cache 会让整个过程变慢,且无法跳过已损坏 ZIP 的校验环节;真遇到 Corrupted zip file,必须先定位并删除那个 ZIP 文件本身。











