编程 PHP 以 40:0 停止背书 PEAR:go-pear.phar 还在你的构建里跑吗

2026-10-23 21:07:52

PHP 以 40:0 停止背书 PEAR:go-pear.phar 还在你的构建里跑吗

来源:https://dev.to/projektgopher/this-week-in-php-internals-oct-22-2026-ii8

PEAR 是 PHP Extension and Application Repository,历史上随 PHP 一起分发。./configure --with-pear 会下载并执行 go-pear.phar,由它安装 PEAR 包管理器;pecl 则从 pecl.php.net 通道安装 C 扩展。

Nick S. 的 RFC 在本周一关闭投票,结果是 40 票赞成、0 票反对、无弃权。PHP 不再背书 PEAR,静态归档保留在线,一直到 2027 年底。

归档还在,可执行文件也还在

Sebastian Bergmann(PHPUnit 维护者)指出:归档期间,php.net 仍在继续提供可执行代码,其中包括 go-pear.phar —— 这个文件在 2019 年 1 月曾被替换成恶意副本。

“静态归档”只说明内容不再更新,不说明分发链路已经关闭。在 2027 年底之前,这些 URL 仍然会返回文件,而 go-pear.phar 本身是可执行的 PHAR,下载即运行。

两条建议:签名清单与哈希固定

Bergmann 给出两个具体方向:

  1. 为归档中的每个文件提供带签名的 SHA-256 清单。下载方拿到文件后可以逐字节比对,确认内容与发布时一致,而不是只能信任服务器当前返回的东西。
  2. 对 PHP 构建期下载并执行的安装器做哈希固定。./configure --with-pear 的流程是下载 go-pear.phar 然后执行它,这个输入应该被 pin 住,哈希不符就中止构建。

下线节奏:brown-out 与 tombstone

直接关停的麻烦在于,遗忘的自动化会在某个不确定的时刻突然失败,而错误信息通常只是一个 404,排查成本高、定位慢。

Bergmann 建议在最终下线之前先安排 brown-out:让这些调用提前失败,并且以可预期的方式失败,把问题暴露在还有人、还有时间修的时候。

下线之后,不要留一个裸 404。放一个 tombstone PHAR,在文件里说明 PEAR 已经停止、发生了什么、应该往哪里迁移。PHPUnit 在自己的 PEAR 服务器关闭前做过同样的处理。

自查清单

1. 构建脚本里的 --with-pear 与 go-pear.phar

grep -rn -- "--with-pear\|go-pear\.phar" .
grep -rn -- "pear install\|pecl install" .

检查范围包括 Dockerfile、Makefile、CI 配置文件、包一层 configure 的构建脚本,以及任何从源码编译 PHP 的地方。如果编译命令里带着 --with-pear,这条链路就会在 configure 阶段下载并执行安装器。

2. pear / pecl 通道依赖

pecl install 走的是 pecl.php.net 通道,这条路径与 PEAR 背书是两件事,但通过 pear 包管理器安装的纯 PHP 库(各种 pear install xxx 的依赖)需要单独确认。列一下现有内容:

pear list
pecl list

逐个判断有没有 composer 侧的替代包。

3. CI 缓存

CI 缓存里经常留着 ~/.pearrc、临时 pear 下载目录、缓存下来的 tgz。缓存命中会掩盖上游已经变化的事实——本机跑得通,换个干净 runner 才炸。清理一次缓存,强制冷启动完整跑一遍构建。

4. 容器镜像里的残留

基础镜像可能预装了 pear/pecl,或者历史层里留下了 pear 安装的包:

docker run --rm  sh -c 'command -v pear pecl; pear list 2>/dev/null'

同时看一下 /usr/local/lib/php、/usr/lib/php 下是否有残留的 pear 包目录。

迁移路径

  • 纯 PHP 依赖:迁到 composer,composer.json + composer.lock 入库。
  • C 扩展:直接用 pecl install,或改走发行版包管理器、预编译扩展包。pear 包管理器在这个环节不再需要。

pin 与校验

  • composer.lock 必须提交,CI 用 composer install 而不是 composer update。
  • 构建期确实需要下载安装器时,先校验再执行:
echo "  go-pear.phar" | sha256sum -c -
  • 仍需从归档拉取文件时,用 Bergmann 提议的签名 SHA-256 清单逐项比对,而不是只依赖 HTTPS。

最省事的路径还是第一条:把 --with-pear 从构建里删掉,让构建过程不再下载并执行 php.net 上的任何东西。

复制全文 生成海报 PHP 供应链 运维 构建

推荐文章

程序员茄子在线接单