必须删除 composer.lock 并配合 --no-cache 或 COMPOSER_CACHE_DIR=/dev/null 才能强制重新解析 composer.json;仅 update、清缓存或删 vendor 均无效,因它们仍依赖 lock 文件或本地缓存。

必须删掉 composer.lock,再配合 --no-cache 或 COMPOSER_CACHE_DIR=/dev/null 才算真正强制重新解析 composer.json —— 仅用 composer update 或清缓存都不够。
为什么 composer update 不等于重新解析 composer.json
它默认基于现有 composer.lock 做增量更新:保留已锁定的间接依赖版本,只按你显式指定的包(或全部)尝试升级。即使 composer.json 里把 "monolog/monolog": "^3.0" 改成了 "^4.0",只要 lock 文件里还锁着 3.5.0,update 就可能直接跳过求解,甚至报错“无法满足要求”。
-
composer update读的是 lock → 解析约束 → 尝试升级,不是从头读composer.json - 删
vendor/后直接composer install?它仍会复原 lock 里的旧版本,不碰composer.json的新约束 -
composer clear-cache只清 ZIP 和元数据缓存,lock 文件毫发无损,解析起点没变
真正强制重新解析的三步组合
目标是让 Composer 忽略所有历史锚点,完全以 composer.json 为唯一输入,重新走一遍依赖求解流程。
- 删掉
composer.lock(关键!这是最常被漏掉的一步) - 删掉
vendor/(可选但推荐,避免残留文件干扰 autoload 或运行时行为) - 执行
composer install --no-cache,或更彻底地:COMPOSER_CACHE_DIR=/dev/null composer install
这时 Composer 会:读 composer.json → 拉取最新元数据(跳过本地 repo 缓存)→ 全新求解依赖树 → 生成新 composer.lock → 下载并安装所有包。
--refresh 不适用:它只刷新元数据,不重解析
composer update --refresh(≥2.5)确实会删除本地 packages.json 和 provider-*.json,但它仍基于当前 composer.lock 工作——只是换了一套元数据去验证和微调已有锁定,不会丢弃 lock 重来。
- 它解决的是“镜像源更新了但本地没感知”的问题,不是“我想按新写的
composer.json重算一切” - 如果你刚改完
composer.json并希望立刻生效,--refresh无效,必须删 lock - 误用
--refresh+update,结果可能是:元数据新了,但 lock 还卡在旧版本,最后啥也没更新
容易被忽略的缓存干扰点
即使删了 lock 和 vendor,如果没处理缓存,Composer 仍可能从 ~/.composer/cache/files/ 快速解压一个旧 ZIP,导致你以为重装了,实际用的是上周缓存的代码。
- 查缓存位置:
composer config --global cache-dir - 最稳妥是加
--no-cache或设COMPOSER_CACHE_DIR=/dev/null,确保 ZIP 也走网络下载 - 别手动
rm -rf ~/.composer/cache:Composer 会重建目录结构,但可能残留损坏的 ZIP,不如用官方命令composer clear-cache清理后再加--no-cache
真正干净的重解析,核心就两点:lock 文件不存在 + 缓存被绕过。其余都是辅助。











