断网时 composer install 失败是因为默认会联网校验元数据,必须加 --no-network 参数才能离线安装,前提是 composer.lock 未修改且 vendor 完整。

断网时 composer install 为什么失败?
因为默认行为会尝试连接 Packagist,即使 vendor/ 已存在且 composer.lock 没变,Composer 仍要校验包元数据、检查更新、甚至下载 zip 包——这些全依赖网络。不是“有缓存就能用”,而是“没网就卡在 metadata fetch 阶段”。
必须加 --no-network 参数才真正离线
这个参数告诉 Composer:别发任何 HTTP 请求,只信本地已有内容。但它有严格前提:
-
composer.lock必须存在且未被修改(git status显示 clean) -
vendor/目录需完整,或至少包含所有lock中声明的包(哪怕只是旧版本) - 不能同时用
--update或--with-dependencies等触发网络操作的选项
正确命令:composer install --no-network。漏掉这个参数,哪怕你本地缓存了全部 zip,它照样报 Could not fetch packages。
composer.lock 是离线安装的唯一权威依据
它不是“建议清单”,而是精确到 commit hash 或 version 的锁定快照。如果有人手动改过 require 再没跑 composer update,lock 就和 composer.json 不一致——此时 --no-network 会直接报错退出,而不是“按旧 lock 装”。常见误操作:
- 编辑
composer.json后忘记composer update --lock - Git 合并冲突后手修了
composer.json,但没同步修lock - CI 环境用了
--prefer-dist,但本地是--prefer-source,导致 vendor 结构不兼容
验证方式很简单:composer install --dry-run(不加 --no-network)看是否提示“Nothing to install or update”;如果是,再切到断网环境跑 --no-network 才稳。
vendor 里缺包?那不是断网问题,是缓存没配对
--no-network 不会补全缺失的包,它只跳过网络校验,然后硬装 lock 里写的路径。如果 vendor/symfony/console 根本不存在,它不会报“找不到包”,而是抛出 Class 'Symfony\Component\Console\Application' not found 这类运行时错误——因为 autoload 失败了。
预防手段只有两个:
- 日常开发确保每次
composer install或update成功后,vendor/和composer.lock一起提交(.gitignore 别乱删 vendor) - 用
composer show --installed对比composer.lock列表,快速发现漏装包
离线环境最麻烦的从来不是网络,而是你以为“上次能跑,这次肯定行”,结果 vendor 早被人删了一半还浑然不知。










