composer status 显示“modified”并非因手动修改vendor,而是依赖包安装后自动生成缓存、日志等临时文件,或post-install-cmd脚本写入、autoload文件重写所致;它仅校验composer.lock记录的源码文件,不涵盖运行时生成物。

composer status 为什么显示 modified 却没动过 vendor
这通常不是文件被手动改了,而是依赖包在安装后自动生成了临时内容。比如 Symfony 写缓存、Laravel 生成 bootstrap/cache/packages.php、或某些包的 post-install-cmd 脚本往 vendor/ 下写了调试日志或配置快照。这些文件本身不在 composer.lock 的哈希校验范围内,但 composer status 会把它们识别为“改动”。
关键点:composer status 只比对 composer.lock 中记录的源码文件(即 dist 包解压出的原始文件),不包括运行时生成物。所以它报 modified,大概率是以下情况之一:
-
vendor/composer/autoload_*.php或vendor/composer/installed.json被重写(每次dump-autoload或install都会变) - 包自身带的
post-install-cmd向vendor/{package}/写了临时文件(少见,但存在) - Git 忽略规则漏掉了
vendor/下某些子目录,导致git status把它们当未跟踪文件上报,间接影响composer status -v输出 - 用
--no-scripts安装过,后续又手动执行了脚本,造成状态不一致
如何让 composer status 忽略临时文件干扰
它本身不支持忽略列表,但你可以控制哪些文件不该出现在 vendor/ 里——核心是管住生成源头和 Git 行为。
实操建议:
- 检查项目是否启用了
"optimize-autoloader": true,它会触发vendor/composer/autoload_classmap.php生成;若不需要极致性能,可关掉减少变动 - 确认
.gitignore明确包含:vendor/**/cache/、vendor/**/logs/、vendor/**/tmp/(如果包真往自己目录下写) - 避免在
composer.json的scripts里往vendor/写东西;改用storage/或var/这类项目级路径 - CI 流程中统一加
composer install --no-scripts,再单独跑清理和缓存命令,让vendor/更“干净”
想真正监控 vendor 里谁在写临时文件,该用什么
composer status 不是文件系统监控工具。要抓实时写入行为,得换系统级手段:
Linux/macOS(推荐):
- 用
inotifywait -m -e create,modify,attrib vendor/监听变化(需安装inotify-tools) - 结合
lsof +D vendor/查当前哪些进程正打开vendor/下的文件
通用轻量法(所有平台):
- 执行前拍快照:
find vendor/ -type f -printf '%P %s %T@\n' | sort > before.txt - 跑完操作再拍一次:
find vendor/ -type f -printf '%P %s %T@\n' | sort > after.txt -
diff before.txt after.txt | grep -E '^[]'—— 只看新增、大小或时间戳变化的文件
注意跳过已知生成文件:autoload_*.php、installed.json、ClassLoader.php,它们的变动不反映依赖变更,只反映本地操作。
为什么不能靠 diff vendor/ 或 git status 判断依赖完整性
因为这两者都只看文件存在性与内容字节,不验证来源可信度。一个被篡改的 vendor/guzzlehttp/guzzle/src/Client.php,只要改得不破坏语法,git status 和 diff 都不会报警——除非你之前 commit 过它。
真正校验依赖是否被污染,唯一可靠方式是:
- 启用实验性功能:
COMPOSER_EXPERIMENTAL=1 composer verify-checksums --strict - 它逐个读取每个包下所有源文件(跳过
.git、tests/、vendor/composer/),合并字节流算 SHA256,再跟composer.lock里的dist.sha256对比 - 不匹配直接报错退出,且返回码非 0,适合放进 CI 检查环节
临时文件写入本身不可怕,可怕的是你误以为“status clean = vendor 安全”。实际生产环境里,verify-checksums --strict 才是最后一道防线,而它完全无视那些自动生成的中间产物。


















