composer怎么在离线时处理依赖中的二进制文件?

1次阅读

离线时 composer install 卡在二进制下载,因 composer 对 “bin” 字段硬编码自动联网校验;解决需手动放入可执行文件、设 “bin-compat”: “full”、删 bin-compat.php、确保 installed.json 和 lock 文件完整。

composer怎么在离线时处理依赖中的二进制文件?

离线时 composer install 会卡在二进制文件下载(比如 phpunitlarastanpest 的 phar 或预编译二进制),因为默认行为是每次从 bin-compatbin-links 指向的远程 URL 下载,而不是复用已缓存的二进制。

为什么 composer install --no-scripts 还是会下载二进制?

因为很多包把二进制下载逻辑写在 post-install-cmdpost-autoload-dump 脚本里,这些脚本即使加了 --no-scripts,只要 composer.json 里声明了 "bin" 字段,Composer 就会在安装后自动尝试拉取或校验——这是 Composer 本身对 bin 的硬编码行为,不走脚本控制。

  • bin 字段声明的路径(如 "bin": ["vendor/bin/phpunit"])会触发 BinCompilers 流程,该流程默认联网检查 hash 和下载
  • 即使本地 vendor/bin/phpunit 已存在且可执行,Composer 仍可能去请求 https://github.com/sebastianbergmann/phpunit/releases/download/... 来比对
  • 这个行为在 composer v2.5+ 中更激进,尤其当 bin-dir 不在默认位置或 config.bin-dir 被自定义时

离线可用的二进制必须提前“固化”进 vendor 目录

不能依赖缓存或临时复制;必须让 Composer 认为二进制是“已安装完成”的状态。核心是绕过它的自动下载逻辑:

  • 手动把目标二进制(如 phpunit-10.5.10.phar)放进 vendor/bin/,并确保权限为 0755
  • 在项目根目录运行 composer dump-autoload,强制刷新 autoload + bin 链接
  • 删掉 vendor/composer/bin-compat.php(如果存在),它会干扰离线判断
  • 关键一步:在 composer.jsonconfig 块中加 "bin-compat": "full",并确保没有 "bin-dir" 覆盖默认值(即保持 vendor/bin

composer install --no-plugins --no-scripts 仍失败?检查这几个点

常见报错像 file_get_contents(https://...): failed to open streamCould not parse version constraint ^10.0: Invalid version String "^10.0"(其实是网络超时导致解析失败),问题往往不在命令参数本身:

  • 确认 vendor/composer/installed.json 存在且完整——离线时它必须由上一次在线 install 生成,否则 Composer 会试图重拉元数据
  • 检查 composer.lock 是否包含 dist.shasum 字段:没有的话,离线时无法跳过完整性校验,会卡在 hash 请求
  • 某些包(如 spatie/binary-parser)会通过 require-dev 引入带 bin 的工具,但没显式声明 bin,这种要手动补到 composer.jsonbin 数组里,否则 Composer 不识别它是“可执行文件”
  • windows 下注意路径分隔符:如果提前复制了二进制,确保 vendor/bin/xxx.bat.exe 文件存在,且 composer.jsonbin 列表包含对应扩展名

真正麻烦的是那些动态生成二进制的包(比如用 roave/security-advisories 配合 composer-unused 时触发的 runtime 编译),它们没法靠“提前放好文件”解决——得在上线前就用相同 PHP 版本+扩展组合,在干净环境中跑一遍完整 install,再把整个 vendor/ 打包带走。

text=ZqhQzanResources