只拷 vendor 目录无法支持 composer require/update,因为缺少 packages.json 元数据和合规命名的 zip 归档,二者是依赖解析与安装的基础;必须配合 composer_disable_network=1、正确配置本地源及验证 zip 一致性才能实现真正离线。

为什么只拷 vendor 目录无法支持 composer require/update
因为 vendor/ 里只有已安装的代码和 autoload 文件,没有元数据——packages.json 和每个包的 .zip 归档才是 Composer 解析依赖、执行新增或更新操作的基础。缺了 packages.json,composer require 会直接报 Could not fetch packages.json,哪怕所有 ZIP 都在本地也无用。
常见错误是导出时只打包 vendor/ 或只复制缓存里的 ZIP,漏掉根目录下的 packages.json;更隐蔽的问题是 ZIP 文件名不合规,比如写成 monolog-monolog-3.5.0.zip 才合法,而 monolog/monolog-3.5.0.zip 或 monolog_monolog-3.5.0.zip 会被忽略。
-
packages.json必须放在镜像根目录,且需包含所有间接依赖(如你没 requirepsr/log,但monolog/monolog依赖它,它的元数据也得存在) - ZIP 文件必须用
composer archive验证:内容与composer.lock中的dist.shasum完全一致 - 推荐用
packagist-mirror工具导出,比手写脚本或改 Satis 配置更可靠,尤其对递归依赖覆盖更全
如何配置项目让 Composer 真正只读本地镜像
仅把镜像文件放好还不够。Composer 默认仍会尝试访问 https://repo.packagist.org,哪怕你已经在 composer.json 里加了 {"type":"composer","url":"http://192.168.10.100"},它也可能 fallback 到官方源——这是设计行为,不是 bug。
必须组合两件事:显式声明源 + 强制禁用网络。否则插件(如 symfony/flex)可能绕过配置偷偷联网。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 项目
composer.json顶部加两个仓库:{"type":"composer","url":"http://192.168.10.100"}(读packages.json) +{"type":"artifact","url":"./packages/archives"}(读 ZIP) - 执行前设环境变量:
COMPOSER_DISABLE_NETWORK=1(Linux/macOS:export COMPOSER_DISABLE_NETWORK=1;Windows CMD:set COMPOSER_DISABLE_NETWORK=1) - 删掉全局干扰项:
composer config -g --unset repo.packagist和composer config -g --unset http-proxy - 验证是否生效:加
-v运行composer install,输出中应出现Reading packages.json from http://192.168.10.100/packages.json,而非任何Downloading https://repo.packagist.org/
离线镜像服务要不要搭 Nginx/Apache
不要。镜像本质是一堆静态文件:packages.json、一堆 vendor-name-package-version.zip、以及可选的 provider JSON。只要能通过 HTTP 路径访问到这些文件就行,不需要动态服务。
用 Python 快速起一个 HTTP 服务即可:python3 -m http.server 8000(当前目录即镜像根目录),然后把 URL 改成 http://localhost:8000 测试;或者直接用 file:// 协议(但部分旧版 Composer 不支持,慎用)。
- 如果必须走
file://,确保composer.json中url字段为file:///path/to/mirror(三个斜杠,绝对路径) - 用
curl -I http://192.168.10.100/packages.json先确认返回 200,再让 Composer 读 - 别在镜像目录里留
.git或隐藏文件,某些 Composer 版本会因权限或解析失败静默跳过整个源
内网机器上执行 install 时仍报 “Package not found” 怎么办
这不是包丢了,而是 Composer 在解析阶段卡在元数据校验。最常踩的坑有三个:锁文件里含 dev-main 分支、dist.url 是 https:// 开头、或 PHP 环境不一致。
- 联网机上先运行
composer update --lock,强制把所有dev-分支转为语义化版本(如2.10.0) - 检查
composer.lock里每个包的dist.url字段,不能以https://开头;若存在,说明镜像没覆盖全,或 Satis 没生成对应 ZIP - 确保内网 PHP 版本、架构(
x86_64/aarch64)、关键扩展(ext-zip、ext-openssl)与外网打包机完全一致 - 临时验证是否真断网:往
/etc/hosts加127.0.0.1 repo.packagist.org,再跑composer install -v,看到Connection refused才算到位
真正难的不是打包,是让所有间接依赖的元数据和 ZIP 同时就位——漏一个 psr/container,composer install 就会在 provider 请求阶段失败,且错误提示不直观。










