夜雨聆风学习资料网

ARTICLE · 1261984

从源码编译一次 PHP,你才知道扩展和测试是怎么跑起来的

从源码编译一次 PHP,你才知道扩展和测试是怎么跑起来的
线上跑着的 PHP 和你本地那个版本对不上,同一个函数行为不一样;或者你想给某个扩展提个修复,把仓库拉下来,发现卡在生成 configure 这一步。
https://www.php.net

这类问题最后都会指向同一件事:你得能自己把 PHP 编出来。

PHP 官方源码仓库的 README 并不长,但它提供了一条可以完整照着走的路径:装依赖、生成 configure、编译、跑测试、安装、装扩展。从头走一遍,很多原本难排查的问题就有了解法。

它是什么,适合谁来碰

README 对 PHP 的定位写得很直接:一门通用脚本语言,尤其适合 Web 开发,快、灵活、务实,从个人博客到全球访问量最大的站点都在用。这不是宣传语,是官方给自己的定义。

这个仓库是 PHP 解释器本身的源码,不是框架,也不是扩展包。分发协议是 Modified BSD License(SPDX-License-Identifier: BSD-3-Clause),完整手册在 php.net/docs。

它适合的人其实不多,但都很具体:需要自己控制编译参数的后端、要给 PHP 或扩展提 PR 的人、想读解释器实现的人,以及做 CI 镜像、要自己裁剪编译选项的人。

如果你只是想跑个站点,下面第一节讲的预编译包就够了,不用往下折腾。

上面两个徽章对应官方自己的测试流水线和模糊测试状态,点进去能看当前构建是否健康。判断某个版本能不能用,这比翻 issue 列表快。

四个值得单独说的设计

装包和编译,是两条明确分开的路

README 把「预编译包」和「自己构建」分成两节写。Windows 用户直接去 windows.php.net 下压缩包,解压完 *.exe 就能用;其他系统看安装章节。

这条路的场景很明确:你只要一个能跑的 PHP,不关心它怎么来的。本地临时验证脚本、CI 里跑一下单测,用这条最省时间。反过来,只要你有任何一个「想改编译参数」的念头,就必须走源码这条路。

编译依赖按发行版拆好了,直接复制

最小构建需要 autoconf、bison、re2c;默认构建再加 libxml2 和 libsqlite3。README 分别在 Ubuntu、Fedora、macOS(brew 和 MacPorts 两种)上给了完整命令。

省掉的就是那种「make 报错才发现少装了一个包」的来回。尤其是想在 Docker 里写 Dockerfile 的时候,这几行可以直接抄进去,不用再一个个试。

测试套件是自带的,不是可选项

make test 在编译成功后就能跑,默认并行,用最多 10 个检测到的逻辑处理器。

真正有用的是它的两个变量:TEST_PHP_ARGS 和 TESTS。想改并发数,加 -jN;想只跑某个目录,指定路径就行。

场景很实在:你改的是语言层相关的东西,就只跑 tests/lang/,几十秒出结果,不用等全量跑完。改完源码先自查一遍再提 PR,这个过程能省掉不少来回。更细的测试和 QA 说明在 qa.php.net。

扩展和贡献,都有自己的入口

扩展方面,PHP 自带一大批内置扩展,第三方扩展在 PIE Extensions 列表里,用 🥧 PIE, the PHP Installer for Extensions 安装。老的 PECL(pecl.php.net)已经被标记为 deprecated,新项目别再往上靠。

贡献方面规则更硬:新特性必须走 RFC,并且要被开发者投票接受;修 bug 不需要 RFC,但提交信息里要引用 issue 编号——GitHub 上的用 GH-NNNNNN,老 bug 追踪系统的用 #NNNNNN。提前搞清楚这条,能少走一轮「格式不对被打回」。

在 Ubuntu 上完整走一遍

假设你要编一个带调试符号的 PHP。

第一步,装依赖:

sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev libsqlite3-dev

Fedora 换成 dnf:

sudo dnf install re2c bison autoconf make ccache libxml2-devel sqlite-devel

macOS 用 brew:

brew install autoconf bison re2c libiconv libxml2 sqlite

或者 MacPorts:

sudo port install autoconf bison re2c libiconv libxml2 sqlite3

第二步,生成 configure:

./buildconf

第三步,配置。 开发用途建议加 --enable-debug,完整选项用 ./configure --help 查:

# For development./configure --enable-debug# For production./configure

第四步,编译。-j 后面跟并发数,一般等于核心数,用 nproc 查:

make -j4

第五步,跑测试。 默认并行,也可以手动指定 worker 数量:

make TEST_PHP_ARGS=-j4 test

只测某个目录:

make TESTS=tests/lang/ test

想顺序执行,把 -j1 换上去就行。

第六步,安装:

make install

根据你的权限和 prefix 设置,这一步可能需要 sudo。

Windows 上自己构建的流程跟上面完全不同,README 直接指向了 wiki 的 step by step 教程,照着那边走。

编完之后

这套流程真正的价值,并不在于你「又多编了一个 PHP」;更关键的是,你把从源码到跑起来的每一环都摸清了:依赖缺哪个、configure 参数该加什么、测试挂了该去哪个目录定位。

下次再遇到版本差异、扩展编不过、怀疑某个行为是 bug,你手上就有可复现的环境,不用靠猜,也不用等别人复现。

想动手的话,建议先找个干净的容器跑一遍,别在本机主力环境里折腾。

相关学习资料