Composer无真正离线模式,必须设COMPOSER_DISABLE_NETWORK=1并配合--no-network、--prefer-dist、完整dist包及本地路径dist.url才能跳过所有网络请求,否则解析lock文件时即报“Could not fetch”。

Composer 没有真正的离线模式,所谓“离线安装”,本质是让 composer install 完全跳过所有网络请求——这只能靠提前准备 + 严格禁用触发点来实现,不是关掉网线就能跑。
为什么 composer install 断网就报 “Could not fetch”
这不是超时,而是 Composer 在解析 composer.lock 阶段就主动发起 HTTP 请求,去 repo.packagist.org 拉取元数据(比如包是否存在、版本是否合法)。哪怕 vendor/ 已存在、lock 文件也完整,只要没显式禁用网络,它照样会卡在这一步。
常见错误现象:
Could not fetch https://repo.packagist.org/packages.json-
Failed to decode response(其实是 DNS 解析失败后返回空响应) - 日志里出现
Loading composer repositories后直接退出
根本原因不是网络慢,是默认行为强制联网校验。解决路径只有一条:COMPOSER_DISABLE_NETWORK=1 必须设,且必须在运行 composer install 前生效。
composer install --no-network 是什么,什么时候能用
--no-network 是 Composer 2.2+ 引入的专用参数,效果比 COMPOSER_DISABLE_NETWORK=1 更彻底:它直接短路所有 RepositoryManager::fetchPackage() 类调用,不查 API、不验签名、不 fallback 到远程仓库。
但它有硬性前提:
- 必须用
--prefer-dist(否则 source 类型包如dev-main会尝试git clone) -
composer.lock中每个包的dist.url字段必须是file://或本地路径(不能是https://) - 对应 ZIP 包必须已存在于缓存或 vendor 目录中(
~/.composer/cache/files/或vendor/)
典型用法:COMPOSER_DISABLE_NETWORK=1 composer install --no-network --prefer-dist --no-plugins --no-scripts。注意:--no-network 对 composer require 无效,它只作用于 install 和 update。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
vendor 目录能不能直接拷贝过去就用
可以,而且这是最稳的离线部署方式——前提是环境完全一致。
必须检查的点:
- PHP 小版本号必须一致(如 8.1.17 和 8.1.20 可能因 openssl 行为差异导致 autoload 失败)
- 必需扩展必须启用且版本匹配(
ext-zip、ext-openssl、ext-mbstring) - 操作系统架构相同(Linux x86_64 的
vendor/不能直接扔进 Windows) -
vendor/composer/installed.json里不能含绝对路径(打包前建议删掉该文件,再运行composer dump-autoload -o重建)
拷过去后,别急着跑 composer install,直接 require 'vendor/autoload.php' 测试入口文件是否能加载类。如果失败,大概率是 installed.json 路径残留或扩展缺失。
离线添加新包的唯一可行方式:path 仓库
composer require 在离线环境下必然失败,因为它要连 packagist 查包名和版本约束。想加新包,只能把本地目录当仓库用。
操作步骤:
- 把目标包(含完整
composer.json)放到项目内,如./packages/my-utils - 在项目根目录
composer.json中添加:"repositories": [ { "type": "path", "url": "./packages/my-utils" } ] - 运行
composer require vendor/my-utils:dev-main(注意必须用dev-main,path 仓库不支持^1.0这类约束) - 立刻执行
composer dump-autoload -o,否则autoload.php不会包含该包
容易踩的坑:
-
url必须是相对路径,不能写成/full/path - 包名(
vendor/my-utils)必须和其composer.json中的"name"字段完全一致 - 子依赖也得用同样方式提供,否则安装中途会因找不到依赖而中断
真正麻烦的从来不是命令怎么敲,而是 composer.lock 里那一行 "source": {} 或 "minimum-stability": "dev" ——它们不会报错,但会让整个离线流程在目标机上静默失效。

















