根本原因是Composer复用本地缓存的packages.json元数据(15分钟内不过期),导致即使远端已发布新版本,update仍按过期快照判断“无更新”;需用composer update --refresh(≥2.5)强制重载元数据,或手动清理~/.composer/cache/repo/下对应镜像子目录。

缓存失效不是“没更新”,而是 Composer 拿着过期的 metadata 做了错误判断——它以为某个包还不存在、或某个版本还不支持你的 PHP,其实远端早已发布。
为什么 composer update 拉不到新版本?
根本原因常不是网络或镜像问题,而是 Composer 复用了本地缓存的 packages.json 元数据快照,里面没包含新发布的 tag 或分支信息。哪怕 Packagist 上已上线 monolog/monolog v3.0.0,你的本地缓存仍只认到 v2.12.0。
-
composer clear-cache只清压缩包和索引,不强制刷新远程packages.json - 私有仓库或 Satis 服务若未重新生成
packages.json,Composer 会一直读旧文件 -
minimum-stability设为"stable"时,即使远端已有v2.1.0-rc,也不会被纳入候选
手动清理三处关键缓存位置
光跑 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/xxx/.composer/cache/repo/https---packagist.org/packages.json into cache—— 表示已写入新快照 - 如果只看到
Reading xxx from cache,说明缓存没清干净或镜像源没同步
私有仓库或 Satis 用户特别注意
这类场景下,packages.json 是你自己的服务生成的,不是 Packagist 动态维护的。常见坑点:
- Satis 构建后忘记
git push到公开地址,Composer 还在读旧 commit - 私有仓库配置了
"type": "composer",但packages.json文件权限不对(如 644 而非可读) - 自建镜像未启用
allow-plugins或禁用了composer/installers,导致 provider 加载失败
最稳妥的做法是直接 curl 一下你的私有 packages.json URL,确认返回内容含目标包和最新 version 字段。
缓存失效最麻烦的地方在于:它不报错,只是静默地“假装不知道”新版本存在。你得主动掀开它的 cache 目录看一眼,而不是等它自己想起来更新。


















