离线执行 composer update 不可行,必须用 composer install;前提是在联网环境生成完整 composer.lock 和缓存目录 ~/.composer/cache/files/,确保含所有 dist 归档及哈希校验信息。

离线执行 composer update 的前提条件
Composer 本身不支持纯离线更新,它必须能访问包元数据(packagist.org 或私有仓库)才能解析依赖、校验版本、生成锁文件。所谓“离线 update”,本质是提前把所有需要的代码和元信息缓存好,让后续操作不触发网络请求。
- 必须在联网机器上先完成一次完整
composer update,并确保vendor/和composer.lock都已就绪 - 缓存目录(
~/.composer/cache)需完整复制到离线环境,否则即使有vendor/,composer install也可能因缺失 dist 包哈希而失败 - 如果项目用了私有包或自定义仓库,这些源的
packages.json必须已缓存(可通过composer config --list查看是否启用了cache-files-ttl等影响缓存命中的配置)
composer install 是离线场景的正确命令
composer update 在离线时必然报错,典型错误是:Could not fetch <a href="https://www.php.cn/link/307e9c61450651aa146fa8da4ddd4906">https://www.php.cn/link/307e9c61450651aa146fa8da4ddd4906</a> 或 Failed to decode response: file_get_contents(): failed to open stream: No such file or directory。真正该用的是 composer install——它只读 composer.lock,不查远程仓库。
- 确保离线机器上有完整的
composer.lock(含所有包的dist.url和dist.shasum) - 确保
~/.composer/cache/files/下存在对应包的 zip/tar.gz 缓存(路径形如vendorname/packagename/<shasum>.zip</shasum>) - 运行前可加
--no-interaction --no-plugins --no-scripts减少意外依赖 - 若提示
Package x is not installed,大概率是缓存缺失或composer.lock里记录的 dist URL 指向了外部地址(比如 GitHub),此时需提前下载并重映射
如何预加载所有 dist 包供离线使用
单纯复制 vendor/ 不够,因为 Composer 默认不会把 zip 包留在本地;它可能只留解压后的代码。要让 composer install 完全离线,必须让缓存目录包含所有 dist 归档。
- 在联网机器上执行:
composer install --no-dev && composer dump-autoload,再运行composer clear-cache && composer install --no-dev—— 第二次 install 会强制重新下载并缓存所有 dist - 检查缓存是否齐备:
find ~/.composer/cache/files -name "*.zip" | wc -l,数量应 ≥composer.lock中packages条目数 - 若用私有 Git 仓库,需配置
"dist": {"url": "file:///path/to/local/archive.zip"}并提前生成归档,否则 Composer 仍会尝试走 git clone(需要网络) - 注意 PHP 版本兼容性:缓存的 zip 包若含
platform限制(如"php": "^8.1"),在低版本 PHP 离线机上会跳过安装,而非报错
常见失效场景与绕过方式
有些看似“离线可用”的情况,实际仍会触网,原因常被忽略:
-
composer install启用了plugin-api(如hirak/prestissimo),某些插件会在安装时校验更新,需在联网时先禁用:composer global config plugin-api false -
composer.lock中的content-hash与当前composer.json不匹配,会导致 Composer 强制重新 resolve(需联网),此时只能删 lock 重来(但那就不是离线了) - 使用了
path类型仓库,且路径是相对地址(如../my-local-package),离线机上该路径不存在,就会 fallback 到 packagist —— 应改用绝对路径或提前 symlink -
composer install --prefer-dist是默认行为,但如果缓存里只有 source(git clone 结果),它仍会尝试 fetch dist;此时加--prefer-source反而更稳,前提是vendor/已完整复制
离线环境最不可靠的其实是时间戳和哈希校验链——任何一个环节缺失或不一致,Composer 就会放弃缓存,转而求助网络。所以别信“复制 vendor 就完事”,得把 lock、cache、PHP 环境三者对齐。










