Composer metadata缓存导致update拉不到新版,需清理~/.composer/cache/repo/https---packagist.org/、vendor/composer/installed.json和composer.lock三处,并用--dry-run -v验证是否重下packages.json。

Composer 的 metadata 缓存确实会导致 composer update 拉不到最新包版本,尤其是私有仓库或 Packagist 新发布的版本延迟出现时,手动清理缓存是最直接有效的解决方式。
为什么 composer clear-cache 有时不生效?
因为 composer clear-cache 只清空本地缓存目录(如 ~/.composer/cache/),但 Composer 在执行 update 时还会读取已下载的 packages.json 元数据快照(存在 vendor/composer/installed.json 和 composer.lock 中的约束),更重要的是:Packagist 的 metadata 是按仓库分片缓存的,且部分缓存可能被写入 ~/.composer/cache/repo/https---packagist.org/ 下的 packages.json 和 provider-* 文件,而 clear-cache 并不强制刷新远程元数据索引。
-
clear-cache删除的是压缩包、zip 文件和已解析的 repo 索引,但下次update仍可能复用旧的packages.json快照 - 若项目锁定了
"minimum-stability": "stable"或"prefer-stable": true,即使远程已有v2.1.0-rc,也不会触发更新 - 私有仓库(如 Satis / Private Packagist)需额外确认其
packages.json是否被正确生成并可公开访问
真正要删的三个关键缓存位置
除了运行 composer clear-cache,还需主动清理以下三处:
-
~/.composer/cache/repo/https---packagist.org/—— 存放所有包的 provider 映射和 packages.json 主索引 -
vendor/composer/installed.json—— 当前已安装包的精确版本快照,影响composer show输出 -
composer.lock—— 不是缓存但会锁定旧版本;若想拉新版本,必须删掉它再composer update
推荐组合操作:
composer clear-cache rm -rf ~/.composer/cache/repo/https---packagist.org/ rm -f vendor/composer/installed.json rm -f composer.lock composer update
如何验证 metadata 是否已刷新?
执行 composer update --dry-run -v 后观察输出中是否包含类似:
Downloading https://packagist.org/packages.json Writing /home/user/.composer/cache/repo/https---packagist.org/packages.json into cache
如果看到 Downloading 行,说明 Composer 正在重新拉取远端元数据;若只显示 Reading ... from cache,则仍走旧缓存。也可临时加 --no-cache 强制跳过所有本地缓存:
composer update --no-cache --dry-run
注意:--no-cache 会显著变慢,仅用于诊断,不要长期使用。
私有仓库更新滞后怎么办?
如果你用的是自建 Satis 或 Toran Proxy,metadata 缓存逻辑不同:
- Satis 的
packages.json必须手动重新生成:php bin/satis build satis.json web/ - Toran Proxy 需登录后台点击 “Refresh all repositories” 或调用 API:
curl -X POST https://your-toran.com/api/v1/repos/refresh - 确保 Composer 配置中该仓库的
type是composer,且url末尾不含/packages.json(应为根路径,如https://packages.example.com)
另外检查 composer.json 中是否误加了 "repositories": [{"packagist": false}] 却没补全私有源,这会导致完全无法回退到 Packagist 查询。
最常被忽略的一点:composer update 默认只更新 require 中显式声明的包,哪怕 metadata 刷新了,require-dev 或未声明依赖的子依赖也不会自动升级——得用 composer update --with-all-dependencies 或指定包名如 composer update monolog/monolog 才行。










