不能用 composer show 或 composer outdated 对比,因其仅反映单环境 vendor/ 和 composer.lock 状态,受终端宽度、排序、--no-dev 等影响而结果不一致,且无法体现另一环境实际安装的包(如生产已删 phpunit 而本地未删),更不揭示依赖路径差异导致的行为分叉。

直接比对 composer.lock 文件是最准、最轻量、最可落地的方式;其他方法(如 composer show、composer outdated)只反映单环境状态,无法跨环境对比。
为什么不能用 composer show 或 composer outdated 对比?
这些命令只读当前环境的 vendor/ 和 composer.lock,输出受终端宽度、排序逻辑、是否含 --no-dev 等影响,每次执行都可能不一致。更关键的是:它们不体现“另一个环境”到底装了什么——比如生产环境删了 phpunit,但本地没删,composer show 在本地跑不出这个差异。
-
composer show --locked默认按字母序输出,而依赖树实际是图结构,顺序不等价于关系 -
composer outdated只查“有没有新版本”,不告诉你“生产环境用的是哪个旧版本” - 若某包在本地是
dev-main(path repo),composer show会把它算进去,但生产环境不可能有这个路径
怎么安全导出并标准化两个 composer.lock?
核心是让两个文件可被 diff 工具稳定识别——重点不是“看起来一样”,而是“结构一致、字段对齐”。手动编辑或复制粘贴极易引入空格、换行、编码差异。
- 从生产环境拿到最新
composer.lock,重命名为composer.lock.prod(不要改内容) - 本地先运行
composer update --lock,确保composer.lock是当前composer.json的最新解析结果(避免缓存导致误判) - 用
jq -S . composer.lock > lock.local.json和jq -S . composer.lock.prod > lock.prod.json格式化,强制键序一致 - 注意:若两边
composer.json中"platform"配置不同(如 PHP 版本),lock文件必然大量差异,需先对齐再比
用 diff 聚焦看哪些字段?
全量比对 packages 数组太嘈杂,真正影响行为的只有几个字段。用 grep 过滤后看,效率高且不易漏关键变更:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 关注
"name"和"version":版本号变化直接决定 BC 是否断裂 - 关注
"source": {"reference":Git commit hash 变动说明用了不同代码快照(尤其 path repo 或 VCS 包) - 关注
"dist": {"shasum":哈希变了但版本没变?可能是包被重新打包,需警惕篡改或构建污染 - 避开
"time"、"type"、"autoload"等低风险字段——除非你明确在审计 autoloader 行为
示例命令:diff -u lock.local.json lock.prod.json | grep -E '("name"|\"version\"|\"reference\"|\"shasum\")'
发现版本一致但行为异常?查依赖路径差异
composer.lock 显示 monolog/monolog 都是 3.5.0,但本地日志正常、生产报错,大概率是上游拉取路径不同:本地经 symfony/console v6 引入,生产经 laravel/framework v10 引入,两者对 psr/log 的约束不同,最终加载的 LoggerInterface 实现可能不兼容。
- 分别在两边执行:
composer show --tree monolog/monolog,观察父级包及其版本 - 重点比对:是否出现
require-dev包意外进入生产依赖树(比如phpunit/phpunit出现在--no-dev安装后的树里) - 若生产无 CLI 权限,可用
composer install --dry-run --no-dev模拟,再结合composer show --tree推断实际加载链
这种差异不会体现在 lock 文件的 "version" 字段里,但 runtime 行为已分叉——这也是只比版本号最危险的地方。

















