离线压缩包(vendor.tgz 或 vendor.zip)不能被 composer install 直接读取,因 Composer 不支持从归档解压并跳过校验;必须先解压到 vendor/ 目录,再通过 COMPOSER_DISABLE_NETWORK=1 及 --no-plugins --no-scripts --no-autoloader 组合命令绕过所有网络请求,最后执行 composer dump-autoload -o 确保自动加载生效。

离线压缩包(vendor.tgz 或 vendor.zip)本身不能直接被 composer install 读取——Composer 不支持从归档文件解压并跳过校验,必须先解压到 vendor/ 目录,再用特定命令绕过所有网络请求。
为什么直接解压 vendor 后运行 composer install 还会报错
因为默认行为下,composer install 仍会尝试访问 https://repo.packagist.org/packages.json 校验元数据合法性,哪怕 vendor/ 和 composer.lock 都已存在。这不是“找不到文件”,而是主动发起的 HTTP 请求被阻断。
-
composer.lock中若含"source": {"type": "git"}或"dist": {"url": "https://..."}条目,离线时无法校验,install 会直接退出 - 全局配置残留
repo.packagist(比如之前设过镜像),会导致 fallback 失败,即使环境变量已设 - PHP 版本或扩展(
mbstring、openssl、zlib)不一致,vendor/autoload.php加载失败,报Class not found或require(): Failed opening required
解压后必须执行的最小安全命令组合
前提是:压缩包来自同 PHP 版本、同扩展环境的机器,且已确认 composer.lock 无 source 类型条目、vendor/ 解压完整、composer.json 未改写仓库配置。
- 先设环境变量:
COMPOSER_DISABLE_NETWORK=1—— 这是硬性开关,缺它所有参数无效 - 禁用插件防止隐式联网:
--no-plugins - 跳过脚本避免调用外部命令:
--no-scripts - 暂不重建 autoload(防路径残留干扰):
--no-autoloader - 执行:
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader - 立刻补一记:
composer dump-autoload -o,否则运行时大概率Class not found
打包 vendor 前必须清理的三类隐患
直接 tar -czf vendor.tgz vendor/ 很容易漏掉关键内容,导致离线解压后功能异常:
-
vendor/bin/下的可执行脚本(如phpunit、phinx)权限丢失 —— 用rsync -a替代tar可保留权限 - 被
.gitignore排除但实际运行必需的文件(如某些包的dist/构建产物、resources/模板)—— 解压后需手动验证是否缺失 -
composer.lock中混入了"dev-master"或 Git URL —— 这类条目在离线时不可解析,打包前务必用composer install --no-dev锁死稳定版本
如何验证压缩包解压后真能跑起来
别只测 composer --version 或 ls vendor/,要实打实触发 autoload:
- 在目标机执行:
php -r "require 'vendor/autoload.php'; echo 'OK ';",不报错才算通过 - 如果项目用了 PSR-4 自动加载,再加一句:
var_dump(class_exists('Your\Namespace\SomeClass')); - 临时把
packagist.org加进/etc/hosts(127.0.0.1 packagist.org),再跑composer install -v,看到Connection refused才说明网络通路真正被切断
最常被忽略的是 COMPOSER_DISABLE_NETWORK=1 的作用范围——它只影响当前 shell 进程,Dockerfile 里写 RUN composer install 却没设 ENV,或 CI 脚本里漏掉前缀,都会让整个离线流程失效。不是“差不多能用”,而是“差一个环境变量就全盘崩溃”。











