composer install 不能替代校验,因为它仅依据 composer.lock 安装且不检测 vendor 文件是否被篡改;真正有效的校验需比对源码指纹,可通过启用 Composer 内置完整性校验或手动验证 dist shasum 实现。

composer install 为什么不能替代校验?
因为 composer install 只按 composer.lock 拉包,不检查 vendor 里现有文件是否被改过。哪怕你悄悄改了 vendor/autoload.php 一行注释,它也照常执行,完全不报错。
真正要发现篡改,得靠主动校验机制——不是“装没装对”,而是“有没有被动过”。
用 composer validate --strict + composer show --installed 不够用
composer validate --strict 只核对 composer.json 格式和依赖逻辑,跟 vendor 文件内容无关;composer show --installed 只列已装包名和版本,不读文件哈希。
它们都跳过了最关键的一步:比对源码指纹。
可行路径只有两个:
- 启用 Composer 内置的完整性校验(需提前配置)
- 手动比对
composer.lock中记录的 dist zip 哈希与本地解压后实际文件
开启 vendor 目录自动校验(require-dev + scripts)
Composer 本身不提供运行时 vendor 扫描,但可以通过 composer.lock 中的 dist.shasum 字段做事后验证。前提是包走的是 dist 安装(默认行为),且未被设为 "source": true。
推荐在 composer.json 的 scripts 里加一条校验命令:
"scripts": {
"verify-vendor": "php -r "foreach (json_decode(file_get_contents('composer.lock'), true)['packages'] as $p) { if (!empty($p['dist']['shasum']) && is_dir("vendor/".$p['name'])) { $zip = file_get_contents($p['dist']['url']); if ($zip === false) continue; $h = hash('sha256', $zip); if ($h !== $p['dist']['shasum']) { echo "FAIL: " . $p['name'] . "\n"; exit(1); } } } echo 'OK\n';""
}
注意这个脚本只适用于 dist 安装的包,如果项目用了 "prefer-source": true 或某些包强制走 git clone,dist.shasum 就为空,这段逻辑直接跳过——这也是最容易被忽略的兼容性盲区。
生产环境部署前必须跑 verify-vendor
CI/CD 流水线里,composer install 后立刻执行 composer run verify-vendor,能捕获两类问题:
- 运维手动进 vendor 改代码(比如打补丁没走 patch 方案)
- 磁盘损坏或传输中断导致 zip 解压不全,文件内容和预期哈希对不上
别指望开发机上校验一次就一劳永逸——容器重建、多节点部署、甚至 rsync 同步都可能引入静默篡改。只要 vendor 不是只读挂载,就得每次部署都过一遍。
最麻烦的是那些没有 dist.shasum 的包,比如私有 GitLab 包没配 dist 信息,或者用了 path 类型仓库。这种只能靠外部工具(如 git status vendor/*)或自建 checksum 清单,没法靠 Composer 原生能力兜底。











