必须设composer_disable_network=1并配合--no-plugins、--no-scripts、--prefer-dist等参数,提前在联网机生成完整缓存(repo/和files/)及composer.lock,离线机上用file://协议指向本地仓库执行install。

离线工业网中 composer install 报 “Could not fetch packages” 怎么办
直接失败是默认行为,不是 bug。Composer 默认必须联网拉取 packages.json 元数据和 dist ZIP,窄带或断网时会卡在 Fetching packages 或报错退出。不设防就运行 composer install,99% 会失败。
关键不是“怎么让它连上”,而是“怎么让它根本不去连”。必须提前在有网环境固化全部远程资源,并在离线机上用环境变量和参数双重封锁网络路径:
-
COMPOSER_DISABLE_NETWORK=1是硬性前提——加在命令前,任何可能触发 HTTP 的动作(包括校验、元数据读取、插件初始化)都会立即报错退出,强制走本地已有数据 - 必须搭配
--no-plugins --no-scripts --no-dev --no-interaction,否则某些插件(如hirak/prestissimo)或 post-install-cmd 仍会尝试发请求 - 目标机 PHP 版本必须 ≥
composer.lock中所有包声明的require.php最低版本,否则即使禁网也会因平台不兼容被拒绝安装
用 path 仓库方式安装已下载的本地包(如 ffmpeg)
适用于你已手动下载好 ZIP 或 Git 代码,想跳过 Packagist 直接引用。这不是“离线安装 Composer”,而是“让 Composer 认出你硬盘上的东西是个合法包”。常见错误是只放代码、不配 repositories,结果 composer require 一直报 Could not find a matching version。
操作分两步,缺一不可:
- 在项目根目录
composer.json的repositories字段里加一条path类型源:{ "repositories": [ { "type": "path", "url": "./packages/php-ffmpeg" } ] }注意路径是相对当前composer.json的,Windows 下建议用正斜杠或双反斜杠 -
./packages/php-ffmpeg/目录下必须有完整composer.json,含name(如"php-ffmpeg/php-ffmpeg")和version(如"0.16.0"),不能只是源码文件夹 - 执行
composer require php-ffmpeg/php-ffmpeg:0.16.0(版本号必须和本地包内composer.json一致;若无固定版,用dev-main或dev-master)
从联网机提取 dist ZIP 包供离线机直接读取
比复制整个 vendor/ 更可靠。因为 vendor/ 里混着软链、脚本、平台相关二进制,而 dist ZIP 是纯压缩包,结构稳定、校验明确,适合工业环境跨机器复现。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
联网机上执行:
-
composer install --no-install --prefer-dist --no-scripts:只下载 ZIP 到vendor/composer/cache/files/,不解压、不跑脚本 - 同时备份
vendor/composer/cache/repo/https---packagist.org/packages.json——它存着包名到 ZIP 路径的映射,离线时没它,Composer 找不到该用哪个 ZIP - 把整个
vendor/composer/cache/打包传到离线机,比如放到/opt/composer-cache/
离线机上运行:
composer install --no-dev --prefer-dist --repository-url=file:///opt/composer-cache/repo/https---packagist.org/ --cache-dir=/opt/composer-cache/
这个命令会让 Composer 完全忽略远程仓库,只从本地 packages.json 查包名,再按里面记录的路径去 cache/files/ 拿 ZIP 解压,全程无网络调用。
为什么 vendor 目录不能直接拷贝就用
看似最省事,实则工业现场最容易翻车。原因不在 Composer,而在 PHP 运行时和系统层:
- 某些包(如
ext-redis的phpredis)在install阶段才编译 .so,vendor/里存的是源码或占位符,离线机没对应 PHP 头文件和编译器,autoload 就会失败 -
vendor/bin/下的脚本依赖软链接(Linux/macOS)或绝对路径(Windows),换机器后链接断裂,phpunit或phpstan直接无法执行 - post-install-cmd 脚本(如 Laravel 的
php artisan config:clear)若未被跳过,会在离线机上尝试调用外部命令或扩展,报错中断 - 不同 PHP SAPI(CLI vs FPM)对
opcache.restrict_api等配置敏感,vendor/autoload.php可能因权限或配置差异加载失败,错误表现为Class not found,而非网络提示
真正稳定的离线交付,永远是「lock 文件 + dist ZIP + 禁网参数」三者绑定,而不是搬运一个解压后的 vendor/ 目录。










