composer install只按composer.lock安装精确版本,完全忽略composer.json中的版本约束;改json后必须运行composer update同步lock,否则install仍装旧版。

composer install 为什么装的不是 composer.json 里写的版本
因为 composer install 根本不看 composer.json 里的版本约束,它只认 composer.lock 里记录的精确版本。哪怕你把 "guzzlehttp/guzzle": "^7.5.0" 改成 "guzzlehttp/guzzle": "7.5.0",只要没运行 composer update guzzlehttp/guzzle,composer.lock 里还是旧版本,install 就永远装旧的。
常见错误现象:
- 改完
composer.json后执行composer install,vendor/里包版本完全没变 -
composer show guzzlehttp/guzzle显示7.8.1,但composer.json写的是7.9.0 - CI 构建失败,报
Class not found,而本地能跑——大概率是 lock 文件没提交,别人install时退化成隐式update
composer.lock 和 composer.json 的优先级怎么算
composer install 的行为完全由 composer.lock 是否存在决定:
- 有
composer.lock→ 严格按它安装:包括version字段、dist.reference(commit hash)、dist.url、校验和,全部照搬 - 没有
composer.lock→ 自动退化为composer update:重新解析composer.json所有约束,生成新 lock 文件并安装
注意:composer.json 里的 ^、~、* 等写法只在 update 阶段起作用;install 阶段它们是“摆设”。真正锁定版本的,只有 composer.lock 本身。
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
怎么确认实际装的是哪个版本
别只信 composer.json 或 composer show 输出,要交叉验证三处:
- 运行
composer show vendor/package,看versions行是否等于你期望的字符串(注意有无v前缀、+git后缀) - 打开
composer.lock,搜索对应包名,检查"version": "x.y.z"和"source": {"reference": "abc123..."}是否存在且确定 - 进
vendor/vendor/package/目录,看它的composer.json或VERSION文件——有些包会篡改自身元数据,导致composer show显示失真
platform 配置不匹配导致锁文件“失效”
即使 composer.lock 存在,composer install 也可能装错版本或直接报错 Your lock file does not contain a compatible set of packages。根本原因是目标环境的 PHP 版本、扩展(如 ext-zip)或 config.platform 与锁文件生成时的环境不一致。
- 高版本 PHP 生成的 lock 文件,在低版本环境可能降级甚至跳过某些包(比如
monolog/monolog v3.5.0要求 PHP >=8.1,但你本地是 8.0) -
composer.json里没配config.platform,导致 lock 文件默认记录开发机配置,CI 机器一跑就出问题 - 用
composer install --dry-run --no-dev --ignore-platform-reqs=false可提前验证 lock 文件是否适配目标平台
真正可靠的锁定,不是只靠 composer.lock 文件存在,而是它和 config.platform、PHP 实际版本、已启用扩展三者严丝合缝。漏掉任何一环,都可能让“锁定”变成幻觉。










