composer verify-checksums --strict 是唯一能回检 vendor 文件完整性的内置命令,但必须显式启用 composer_experimental=1 环境变量,否则命令未定义;它仅校验 dist 包,跳过 source 安装,且不加 --strict 时失败仍返回 0,ci 无法捕获。

composer verify-checksums --strict 必须加环境变量
这个命令是唯一能回检已安装 vendor 文件完整性的内置手段,但默认不启用。不加 COMPOSER_EXPERIMENTAL=1 就会报错或静默忽略 —— 它不是“可选开关”,而是硬性前置条件。
常见错误现象:直接运行 composer verify-checksums --strict,输出 Command "verify-checksums" is not defined. 或毫无反应。这不是版本问题(≥2.5 才支持),而是环境变量缺失。
- 必须每次执行都带上:
COMPOSER_EXPERIMENTAL=1 composer verify-checksums --strict -
--strict是关键:没它,校验失败只警告、返回码仍是 0,CI 流水线无法中断 - 它只校验
dist安装的包(zip/tar),source安装(git clone)的包直接跳过,不会报错也不会提示 - 排除路径固定:
.git/、tests/、vendor/bin/等非发布内容不参与哈希计算,和 lock 文件中记录逻辑一致
vendor 目录被改后,install 不报错?先看是否走了 dist 路径
很多人发现改了 vendor/autoload.php 后 composer install 仍成功,误以为校验失效。其实根本原因在于:Composer 只在校验下载那一刻比对哈希,落地后就不管了。而你改的是已解压的文件,不是原始 zip。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
真正决定校验是否触发的,是安装时走的是 dist 还是 source:
- 运行
composer install -v,看输出里有没有Downloading https://...;出现Cloning就说明走了--prefer-source,dist.shasum字段完全被忽略 - 检查
composer.json是否设了"preferred-install": {"*": "source"},或全局配置里有同类设置 - 确认
composer.lock中目标包的dist段存在且shasum是 64 字符(SHA-256),40 字符(SHA-1)在新版中已逐步弃用 - 缓存污染也会绕过校验:如果
~/.composer/cache/files/下的 zip 已被篡改,Composer 复用它而不重新下载,自然不触发比对
手动验证 dist shasum 的安全边界在哪
自己下载 zip、算 SHA-256 并比对 composer.lock 里的值,看似最可靠,但实际有三处容易踩坑:
- URL 必须和 lock 文件里
dist.url完全一致 —— 国内镜像源常替换 URL,但没同步更新 hash,导致比对“成功”却内容不一致 - 下载时必须用
-L(follow redirect),否则可能拿到 302 响应体而非真实 zip,哈希必然不匹配 - 解压后计算目录哈希不能简单
sha256sum *:要排除.git/、tests/、vendor/bin/,还要按composer.lock中dist.reference对应的 commit 或 tag 精确提取发布内容 - 这个方法只适用于 public 包;私有仓库或 path 类型包没有
dist段,根本没法走这条路
为什么不能靠 composer validate 或 show --installed 查篡改
这两个命令常被误当作完整性检查工具,但它们根本不读 vendor 目录里的文件内容:
-
composer validate --lock只比对composer.json和composer.lock内部 hash 字段是否匹配,不碰任何 vendor 文件 -
composer show --installed输出的是当前 vendor 里“有哪些包”,但不会校验这些包的代码是否和 lock 文件声明的一致 -
composer install --dry-run --verbose是更接近的替代方案:它模拟安装流程并触发 dist 校验,但前提是 vendor 目录已存在且结构基本完整;空目录会直接跳过校验 - 真正可靠的生产做法是每次部署清空
vendor/,强制composer install --no-cache --prefer-dist,把校验逻辑塞进安装环节,而不是事后补救










