离线开发规范需从缓存路径、仓库类型、网络拦截、命令组合四层同时卡死,漏一层就会触发DNS或HTTP请求;cache-files-dir须显式配置绝对路径并含/files后缀;仅禁用packagist不够,还需用artifact/path仓库并清空默认源;COMPOSER_DISABLE_NETWORK=1是强制前提,否则所有离线参数失效;create-project不支持离线,须改用分步法;vendor迁移要求PHP版本、扩展、Composer版本完全一致。

离线开发规范不是靠“配一个开关”就能生效,必须从缓存路径、仓库类型、网络拦截、命令组合四层同时卡死,漏掉任何一层都会在 install 阶段触发 DNS 查询或 HTTP 请求。
cache-files-dir 必须显式配置且带 /files 后缀
只设 cache-dir 是无效的——Composer 会把 ZIP 包写进 cache-dir/files/,但若没显式指定 cache-files-dir,它就默认回退到 ~/.composer/cache/files,而离线机上这个路径通常为空或不可写。
-
cache-files-dir必须是绝对路径,且末尾含/files(例如/opt/composer-cache/files),不能是/opt/composer-cache - 配完后运行
composer diag,确认输出中Cache files directory行与你设置的完全一致 - 目录权限要允许 PHP 进程用户(如
www-data或当前 shell 用户)执行stat()和open(),否则静默 fallback 到重下 - 旧配置不清理会导致新设置被忽略:
composer config --global --unset cache-dir必须先执行
本地仓库只能用 artifact 或 path,禁用 packagist 是硬性前提
repositories 里加个 "type": "composer", "url": "http://internal" 在离线环境毫无意义——它仍会尝试发起 HTTP 请求。真正可用的只有 artifact(预打包 ZIP)和 path(本地源码目录),且必须全局关闭默认源。
- 禁用 packagist 必须两步:全局执行
composer config --global repo.packagist false;再检查项目级是否残留"repositories": [{"type": "composer", "url": "https://packagist.org"}],有则删 -
artifact类型要求所有包命名严格为vendor/name-version.tar.gz,放在单层目录(如/artifacts/),不能嵌套子目录 -
path类型要求包内composer.json的name字段与require语句完全一致(包括大小写),且必须加@dev后缀,例如composer require my-utils/my-utils:@dev - 验证是否真断网:
echo "127.0.0.1 repo.packagist.org" >> /etc/hosts,再跑composer install -v,看到Connection refused才算到位
COMPOSER_DISABLE_NETWORK=1 是所有离线命令的前提
不设这个环境变量,--no-plugins、--no-scripts 等参数全失效。它不是“建议开启”,而是 Composer 离线行为的总闸门。
- 离线机执行任何
composer install前,必须前置该变量:COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader - 如果
composer.lock中某包的dist.url是https://开头,且未配置对应本地仓库,此变量下会直接报错退出,不会静默跳过 -
create-project命令不支持此变量,它强制联网,离线环境下必须废弃,改用分步法:联网机git clone + composer install --prefer-dist→ 打包整个项目(含 vendor/ 和 lock)→ 离线机执行上述命令组合 - 执行完
install后必须补一记composer dump-autoload -o,否则运行时大概率Class not found
vendor 目录迁移比缓存更简单,但环境一致性是命门
直接复制 vendor/ 是最快方案,但它对 PHP 版本、扩展、Composer 版本极度敏感。不是“能拷过去就行”,而是“必须一模一样才敢动”。
- 源机和目标机的 PHP 版本号(如 8.2.12 vs 8.2.13)、SAPI 类型(CLI/FPM)、关键扩展(
mbstring、openssl、json)必须全部匹配 - 含
post-install-cmd的包(如需要编译的扩展封装)不能靠复制 vendor 解决,必须用artifact或提前在目标机安装对应扩展 - 打包
vendor/时用tar -czf vendor.tgz -C . vendor/,避免.gitignore导致遗漏(比如某些包的dist/目录) - 目标机执行
composer install前,确保vendor/已清空或不存在——残留旧包可能引发版本冲突或 autoload 错误
最易被忽略的是:离线环境里没有“试错成本”。一次 composer install 失败,往往不是因为少配了一个参数,而是某处残留了 packagist 配置、cache-files-dir 指向了父目录、或者 PHP 版本差了一个 patch 号。验证必须落到具体路径和日志行,而不是“看起来没报错”。











