结论:离线使用 Composer 必须设置 COMPOSER_DISABLE_NETWORK=1,否则即使 vendor 和 composer.lock 存在也会因请求 packages.json 而失败;配国内镜像需严格满足键名、type、URL 末尾斜杠三条件;离线安装后须执行 composer dump-autoload -o。

COMPOSER_DISABLE_NETWORK=1;网速慢则换国内镜像,但配错一个字符(比如少斜杠、漏 composer 类型)就等于白配。
为什么 vendor 目录存在还报 “Package not found”
不是文件丢了,是 Composer 每次 install 都会默认请求 https://repo.packagist.org/packages.json 校验元数据——哪怕 vendor/ 和 composer.lock 全在,它也要连一次。这个请求不跳过,除非你主动切断网络通路或加环境变量。
-
COMPOSER_DISABLE_NETWORK=1是硬性前提,不设它,--no-plugins、--no-scripts全无效 - 若
composer.lock里某包的dist.url是https://开头,且没配本地仓库,COMPOSER_DISABLE_NETWORK=1下会直接退出,不是静默忽略 - 验证是否真断网:往
/etc/hosts(Windows 是%SystemRoot%\System32\drivers\etc\hosts)加一行127.0.0.1 packagist.org,再跑composer install -v;看到Connection refused才算到位
怎么配中文镜像才真正生效
卡在 Loading composer repositories,90% 是因为镜像没配对、配全、配准。Composer 2.x 对配置极其严格,三个条件缺一不可:
- 键名必须是
repo.packagist(单数,不能写成repos.packagist或packagist.org) - 中间必须显式传入
composer作为type值(漏掉它,Composer 会 fallback 到官方源) - URL 必须是 HTTPS 且末尾带斜杠:
https://mirrors.aliyun.com/composer/✅,https://mirrors.aliyun.com/composer❌(少斜杠会导致拼成/composerpackages.json,404)
正确命令示例:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
验证是否生效:composer config -g repo.packagist 输出应为 {"type": "composer", "url": "https://mirrors.aliyun.com/composer/"};空、null 或仍是 https://repo.packagist.org,说明根本没写进去。
离线安装最稳的命令组合
前提是已有完整 vendor/ 目录和未改动的 composer.lock,目标机 PHP 版本、扩展(如 ext-zip)、架构需与源机一致。
- 打包前在线机执行:
composer install --no-dev --prefer-dist --optimize-autoloader,确保所有子依赖进vendor/,且无 dev-only 文件 - 删掉这些再打包:
vendor/bin/(Windows 软链失效)、vendor/composer/installed.json(含绝对路径,引发 autoload 异常) - 目标机解压后执行:
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader - 必须补一记:
composer dump-autoload -o,否则运行时报Class not found
想后续还能 require 或 update?必须搭本地镜像
只复制 vendor/ 或只打包缓存 ZIP,无法支持新增依赖——缺的是 packages.json(元数据索引)和合规命名的 ZIP 归档(vendor-name-package-name-version.zip),二者是依赖解析的基础。
- 推荐用
satis构建:写好satis.json,运行php bin/satis build satis.json web/,生成完整packages.json和 ZIP 包 - 把
web/目录拷进内网,用python3 -m http.server 8000启动,访问http://127.0.0.1:8000/packages.json能打开就算成功 - 项目
composer.json中加:"repositories": [{"type":"composer","url":"http://127.0.0.1:8000"}], "packagist.org": false - 执行前先清缓存:
composer clear-cache,否则可能仍读旧缓存
离线场景下,COMPOSER_DISABLE_NETWORK=1 和本地 HTTP 镜像不是二选一,而是两种不同粒度的控制:前者是“彻底封死所有 HTTP 请求”,后者是“把外网请求映射到内网服务”。实际落地时,常要同时考虑 autoload 映射、扩展兼容性、ZIP 命名规范这些细节,漏掉任意一环都可能在运行时报错,而不是安装时报错。


















