必须禁用packagist并配置本地仓库:全局及项目级执行composer config --global repo.packagist false,再设repositories为artifact或path类型,最后加--no-plugins --no-scripts运行install。

composer install 时怎么跳过网络请求?
核心是让 composer install 完全不连远程仓库,只从本地文件读取依赖。这要求提前把所有包的源码(含 composer.json 和 vendor/ 结构)打包好,并配置 Composer 使用本地 packages 目录作为唯一仓库源。
关键操作有三步:
- 用
composer archive或手动zip打包每个已安装的包(含其composer.json),目录结构建议为vendor/{vendor}/{package}/{version}/ - 在项目根目录新建
packages/目录,把所有 zip 放进去;再建packages/packages.json,内容为标准仓库格式({"packages": {...}}) - 修改项目
composer.json的repositories,设为{"type": "package", "package": {...}}或更稳妥的{"type": "composer", "url": "packages/"}(需配合composer serve或静态 HTTP 服务)
注意:"type": "package" 不支持版本别名或分支映射,容易漏包;推荐用 type: composer + 本地 HTTP 服务,兼容性更好。
如何生成可离线复用的 vendor 存档?
直接 tar.gz 整个 vendor/ 不可靠——里面可能含硬编码的绝对路径、.git 目录、dev-only 文件(如 phpunit),且无法跨平台还原(Windows vs Linux 符号链接问题)。
安全做法是只存「可重建」的元数据和源码:
- 运行
composer install --no-dev --prefer-dist --optimize-autoloader确保vendor/干净 - 执行
composer show --format=json > composer-lock.json.bak备份精确版本快照 - 用
composer archive --format=zip --dir=dist/(需插件)或脚本遍历vendor/,对每个包执行git archive --format=zip HEAD | gzip(仅限 Git 源) - 最终打包:把
composer.lock、dist/目录、composer.json一起压缩为project-deps-20261019.zip
还原时,先解压,再运行 composer install --no-interaction --no-scripts,它会严格按 composer.lock 从本地 dist/ 加载,不碰网络。
离线环境里 vendor/autoload.php 加载失败怎么办?
常见错误是 require_once: failed to open stream: No such file or directory,本质是 autoloader 路径写死或未重生成。
必须检查三点:
-
vendor/autoload.php是否存在?如果只备份了源码没运行install,它不会自动生成 - 确认
composer dump-autoload --optimize已在离线机上执行(尤其用了 PSR-4 自定义命名空间时) - 若项目用了
classmap,确保vendor/composer/autoload_classmap.php里的路径是相对的,不是绝对路径(某些旧版 Composer 会写入/home/user/...)
补救方法:删掉整个 vendor/,用 composer install --no-dev 重新生成,全程离线——前提是 composer.json 和 composer.lock 齐全,且所有包都可通过本地仓库解析到。
为什么 vendor 存档在另一台机器上 install 失败?
最常被忽略的是 PHP 版本与扩展约束。比如 composer.lock 里某包声明 "php": "^8.1",但离线机是 PHP 7.4,install 会静默跳过该包,导致后续 autoload 缺类。
排查优先看这些:
- 运行
composer check-platform-reqs,确认当前 PHP 版本、扩展(如mbstring、curl)满足composer.json中的platform声明 - 检查
composer.lock里content-hash是否和当前composer.json匹配;不匹配说明 lock 文件被手改过,不可信 - 用
composer depends {package-name}查依赖链,确认没有间接引入需要网络验证的私有包(如通过vcs类型仓库)
真正可靠的离线部署,从来不是“拷贝 vendor”,而是“保留 lock + 可达的包源 + 环境一致性”。否则哪怕 ZIP 打得再全,PHP 小版本差一级,就可能卡在某个 match 表达式语法上。


















