PHP 新轮询 API 能否改善异步编程
轮询引擎是构建 Reactor 的底层基础,而 Reactor 是事件循环的核心组件。它允许 PHP 代码等待 PHP 文件描述符上的 I/O 事件。这一点是有价值的。
它的弊端是什么?
轮询 API 使 PHP 代码能够创建多个事件循环,这会破坏 SOLID 设计原则。一个应用程序应当只有一个 Reactor。如果两个 PHP 库或框架决定运行各自的事件循环,它们就有相互干扰的风险。
一种常见的反驳是:“这并非问题。只要避免同时使用不兼容的库即可。”
对这种反驳的回应很简单:如果这可以接受,那么为什么还需要面向对象编程和抽象层?
为什么需要抽象?
PHP 长期以来倾向于将底层接口直接暴露给用户空间代码。这个问题可以追溯到语言诞生之初。
首先,PHP 构建在 C 语言之上。
其次,PHP 的设计是有机演化的结果,并非来自一套经过周密规划的架构。
例如,现在已经是 2026 年,PHP 仍然缺少一个优秀的内置进程管理库。开发者往往需要引入整个 Symfony 包,只是为了启动和管理进程。尽管 PHP 是一门高级语言,却仍然暴露底层 socket API。类似的设计不一致在整个生态系统中随处可见。
Fiber 也会违反分层原则。分层的核心思想是,高层抽象不应绕过中间抽象而直接依赖底层。很难准确预测这些违规会在何处变成实际问题,但它们会增加耦合并削弱隔离性。
Rust 通过模块系统提供了更强的代码隔离机制,因此避免了许多此类问题。PHP 缺少这样的机制。更重要的是,框架要想独占 Fiber 的使用权,可靠方式只有确保相互竞争的技术方案永远不会被同时加载。
这些设计决策主要通过生态系统碎片化影响 PHP 开发者。它们制造了多种解决同一问题的方式,而这些方式依赖不同的库和彼此不兼容的方案。系统级功能就是一个典型例子。
PHP 不是系统编程语言,却越来越多地把系统编程概念直接暴露给应用开发者。
一种常见反驳是,PHP 开发者现在可以快速构建原本需要 C 或 C++ 才能完成的东西。
显而易见的问题是:这真的节省时间吗?
使用 C、Rust 以及其他系统语言的开发者,已经习惯于在多个竞争性选项中评估并选择一个库。对于性能关键型软件而言,这很正常,而且通常也是必要的。
PHP 传统上处于不同的生态位。事实果真如此吗?
在 RFC 讨论期间,有人提出了一个合理的问题:
“PHP 为什么需要这样低层级的接口?”
这个问题几乎没有得到关注。
开发者选择 PHP 的原因之一,是希望减少处理系统编程问题所花费的时间。这是理性且具有经济合理性的选择。PHP 提供了一门语言、一个运行时,以及大量能够开箱即用地解决多数常见问题的库。与 Go、C、C++ 或 Rust 相比,这是 PHP 最重要的优势之一,也是这门语言的核心价值主张。
最终得到的结果是什么?
低层级库和 C 扩展仍然没有获得异步能力,因为 PHP 仍然没有提供内置 Reactor。I/O 隔离性被削弱了。PHP 现在正式暴露了一种干扰 I/O 等待过程的机制,而这一设计选择在未来很难轻易撤回。