优先执行composer install --dry-run确认是否可续装;若显示“Skipped”则直接重试install,否则删vendor/autoload.php和vendor/composer/后dump-autoload再install。

composer install 中断后 vendor 不完整,怎么安全续装?
直接删 vendor 重来不是最稳的方案,尤其在 CI 或受限环境里——中断往往意味着部分包已写入、autoload 已生成、但依赖链没走完,强行清空可能触发 autoload 错误或 class not found。
优先执行 composer install --dry-run,看它是否报出“already installed”或“skipping”类提示。如果输出显示大部分包状态为 Skipped,说明 Composer 能识别已安装部分,此时直接再跑一次 composer install 就能续上。
若 --dry-run 报错(比如提示某个包的 autoload 文件缺失),说明中间态损坏较深,这时才需要清理:
- 删掉
vendor/autoload.php和vendor/composer/目录(保留vendor/下其他包目录) - 运行
composer dump-autoload重建自动加载映射 - 再执行
composer install
注意:不要只删 vendor/ 下某几个包目录,Composer 不会自动补全“半截包”,它只认 composer.lock 的完整快照。
为什么 composer show --tree 突然不输出,或只显示一行?
这不是命令坏了,而是环境快照缺失或错位。最常见三种情况:
-
composer.lock不存在或为空 →composer show --tree退化为只读composer.json,且仅展示顶层require,不展开任何传递依赖 -
vendor/目录为空或不匹配composer.lock→ 输出为空或报No composer.json found(实际是找不到已安装包元数据) - 当前不在项目根目录(即没有
composer.json的目录)→ 命令根本无法初始化,直接失败
验证方式很简单:运行 ls -l composer.json composer.lock vendor/,三者必须同时存在且内容有效。如果 vendor/ 是空的,先跑 composer install;如果 lock 缺失,别急着 update,先确认团队是否本就用“无 lock 提交”策略。
composer why --tree 输出中断在某一层,比如停在 laravel/framework 就没了
这通常不是命令失效,而是上游包用了 provide 声明虚拟包。例如 laravel/framework 在 composer.json 里写了 "provide": {"psr/log": "^1.0 || ^2.0"},Composer 就不会继续向下解析它“实际装了哪个 psr/log”,因为逻辑上它自己就“提供”了该能力。
遇到这种情况,想继续追,得换路径:
- 先用
composer show --tree laravel/framework看它自己带了哪些真实子依赖 - 再对疑似提供方运行
composer show laravel/framework | grep provide,确认它声明了哪些虚拟包 - 如果目标包(如
psr/log)确实在provide列表里,那它就不会出现在why --tree的下游,这是设计行为,不是 bug
真正要查“谁最终提供了 psr/log”,用 composer show --who psr/log 更直接——它只扫 require 字段,不绕虚拟层。
CI 环境中 install 反复失败,怀疑是依赖树解析卡死
不是网络慢,也不是磁盘满,大概率是 Composer 在尝试太多无效版本组合。尤其当项目用了宽松约束(如 ^1.0)又混入多个 require-dev 包时,搜索空间会指数级膨胀。
两个低成本干预点:
- 加
--no-dev:CI 构建生产镜像时,require-dev完全不该参与解析,去掉它常能让 install 从超时变秒装 - 锁死平台版本:在
composer.json的config.platform里明确 PHP 和扩展版本,比如{"php": "8.2.12", "ext-gd": "8.2.12"},避免 Composer 在解析时反复试探兼容性
如果仍卡住,别等超时,立刻 Ctrl+C,然后运行 composer show --tree | head -50 —— 看前 50 行有没有重复出现同一包名(比如 symfony/polyfill-* 出现七八次),那是多路径引入的典型信号,得回头检查 replace 或 conflict 配置是否收口到位。











