答案是composer默认复用15分钟内未过期的本地packages.json缓存,导致即使镜像站已更新新版本,update仍按旧元数据计算而忽略新版本;解决方法为≥2.5版本执行composer update --refresh强制刷新元数据,老版本需手动删缓存目录或设composer_cache_dir=/dev/null。

composer update 看不到新版本?元数据缓存根本没刷新
不是镜像没同步,而是 Composer 默认复用本地 packages.json 缓存 15 分钟——哪怕阿里云镜像站已更新了 monolog/monolog v3.6.0,你执行 composer update monolog/monolog 仍会显示 Nothing to install or update。
验证方式很简单:curl -I https://mirrors.aliyun.com/composer/packages.json 返回 200,且响应头含 Last-Modified 时间比你本地缓存文件新,就说明问题出在本地。
-
composer update --refresh(仅 ≥2.5 支持)会清空所有 provider 缓存,但保留 ZIP 包缓存,只重拉元数据 - 老版本(≤2.4)必须手动删缓存目录:
rm -rf $(composer config --global cache-dir)/repo/https---mirrors-aliyun-com-composer -
composer clear-cache不够用:它清的是 ZIP 包和 provider 缓存,不碰packages.json和provider-*.json,下次update仍读旧索引
项目级 repositories 配置会彻底屏蔽全局镜像
很多人配了 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/,却依然走官方源,原因几乎全是项目根目录 composer.json 里写了 "repositories" 字段——它会完全覆盖全局设置,且不报错、不提示。
- 常见陷阱包括:
"repositories": [{"type": "composer", "url": "https://packagist.phpcomposer.com"}](该地址已404) - 漏写
type、URL 少末尾/,导致请求拼成/composerpackages.json直接404 - 静默 fallback 到官方源,日志里看不到任何警告
- 查实际生效配置:
composer config --list | grep repositories.packagist,确认输出是你预期的镜像地址
缓存路径与并发参数不匹配,镜像再快也跑不满带宽
只换镜像不调并发,等于给高速公路装单车道闸机。Composer 2.2+ 默认仅开 3 个并发线程,http-max-concurrent-downloads 才是有效参数(parallel-downloads 已弃用)。
- 执行
composer config -g http-max-concurrent-downloads 8(推荐 8–10,CI 环境可先设为 6) - 并发过高容易触发
file_put_contents(/tmp/): failed to open stream错误 - 该参数只加速 tarball 下载,不加速元数据请求;若镜像未生效,它压根没机会并发
- 缓存目录别挂到 NFS 或 Docker volume 上,
cache-dir应指向 SSD 或高速磁盘
composer.lock 与镜像不同步时的 fallback 行为不可控
composer.lock 记录的是生成时的 dist.url 和 shasum,这些字段来自当时所用源。如果镜像同步延迟(通常 5–15 分钟),composer install 会尝试从 lock 里写的 URL 下载 ZIP,而该 URL 可能指向镜像站上还不存在的包,最终报 404 Not Found 或 Signature mismatch。
- 镜像同步有 lag:阿里云/腾讯云通常 5–15 分钟,华为云可能更长
- 禁用 fallback(如配了
"packagist.org": false)会导致安装失败,应保留默认 fallback - CI 流水线中加验证步骤:
composer install --dry-run 2>&1 | grep -q 'mirrors\.aliyun\.com',失败则中断构建 - 禁止手动编辑
composer.lock中的dist.url字段——它由 Composer 自动填充,改了会导致校验失败











