离线安装 Composer 包的关键是复用 vendor 目录和 composer.lock 文件,确保 PHP 版本、扩展、架构一致,并验证 autoload 和 installed.json 是否正常工作。

离线安装 Composer 包:核心是复用已有的 vendor 和 composer.lock
不能联网时,composer install 本身就能离线工作——前提是目标机器上有完整的 composer.lock 文件,且之前已在另一台环境执行过 composer install 并打包了 vendor 目录。
关键不是“怎么让 Composer 下载”,而是“怎么把依赖的确定状态完整搬过去”。composer.lock 是唯一可信源,它锁定了每个包的确切版本、哈希和源类型(dist / source)。
- 必须确保两台机器 PHP 版本、扩展(如
openssl、zlib)一致,否则某些包在 autoload 或运行时会直接报错 - 不要只拷贝
vendor/autoload.php或部分子目录——Composer 的自动加载逻辑依赖vendor/composer/下的autoload_*.php和installed.json - 如果原环境用了
--no-dev,离线机也得用同样参数,否则composer install会因缺少 dev 包而失败
composer install 离线执行失败的常见原因
报错如 Could not fetch https://repo.packagist.org/packages.json 或 Failed to decode response,说明 Composer 仍试图联网——这不是网络问题,而是配置或文件缺失导致它无法走离线路径。
- 检查当前目录是否有
composer.lock:没有它,composer install会退化为composer update,必然要连网 - 确认
composer.json中没写死"repositories"指向远程地址(比如私有 repo),这种配置会让 Composer 忽略本地 lock 文件 - 运行
composer install --no-interaction --no-progress,避免因交互提示卡住;加-v可看实际加载了哪些文件,确认是否读到了vendor/composer/installed.json
手动拷贝 vendor 的安全边界在哪里
直接复制 vendor 文件夹可行,但仅限于完全相同的运行环境:PHP 小版本号(如 8.1.17 vs 8.1.20)、扩展启停状态、甚至操作系统架构(Linux x86_64 不能直接扔到 Windows 上用)都必须一致。
- 某些包含编译产物(如
ext-redis的.so或.dll),跨系统/架构拷贝必挂 -
vendor/bin/下的可执行文件(如phpunit)头部有硬编码的解释器路径(#!/usr/bin/env php),若目标机php不在 PATH 或版本不匹配,会报Bad interpreter - 建议用
rsync -a --delete拷贝,保留符号链接和权限;别用压缩包解压,容易丢掉 symlink 或 chmod 位
如何验证离线环境真的“就绪”
别只测 composer install 是否不报错,要验证运行时行为。最简单的办法是触发自动加载并检查类存在性:
php -r "require 'vendor/autoload.php'; var_dump(class_exists('Monolog\Logger'));"
如果返回 bool(true),说明 autoload 链路通了;如果报 Class 'Monolog\Logger' not found,大概率是 vendor/composer/autoload_classmap.php 没生成或路径不对。
另一个易忽略点:vendor/composer/installed.json 里记录了每个包的安装方式(dist/source)。若原环境装的是 source(git clone),而离线机没装 git,某些需要 post-install-cmd 的包可能漏执行脚本——这种问题不会在 install 阶段暴露,而是在第一次调用该包功能时才崩。







