True Async 与 PHP 8.6 的原生并发
如果曾构建过需要并发能力的 PHP 应用——比如同时请求多个 API,或者在读取文件的同时查询数据库——就一定体会过“排队等待”的滋味。一个操作必须等前一个操作结束之后才能开始。多年来,解决办法一直是在 PHP 之上再叠加 AMPHP、ReactPHP 或 Swoole 之类的库,因为语言本身从未为此而设计。
True Async 试图从根源上解决这个问题——它不是又一个叠加在 PHP 之上的库,而是直接内建于 PHP 核心的并发模型。而眼下值得关注的原因是:该项目的正式发布版本瞄准 PHP 8.6。
下面就来剖析 True Async 究竟是什么、目前进展如何,以及为什么“它能否真正落地到 8.6”仍是一个值得持续追踪的故事。
True Async 究竟是什么?
想象一下这样的代码:
$page = file_get_contents($url);
$rows = $pdo->query($sql)->fetchAll();
$stats = file_get_contents($api);这三行代码会一行接一行地执行。如果每一行各需一秒,那么总共要等待三秒。
借助 True Async,同样的代码只需用 spawn() 包裹起来,即可并发运行:
// three coroutines running concurrently
$page = spawn(fn() => file_get_contents($url));
$rows = spawn(fn() => $pdo->query($sql)->fetchAll());
$stats = spawn(fn() => file_get_contents($api));
// wait for all of them, cancel if it takes longer than 2 seconds
[$html, $data, $meta] = await_all_or_fail(
[$page, $rows, $stats], timeout(2000)
);现在三行代码同时运行,总等待时间约为一秒——与最慢的那一个操作耗时相当,而不是三者之和。
与 JavaScript 或 Python 中 async/await 的不同之处在于:True Async 的设计目标是,永远不必标记哪些函数是“异步”的、哪些是“同步”的。没有 async function,也不需要在每个函数上点缀新的关键字。普通的同步代码可以直接在协程(coroutine)内原样运行,无需任何改写。
几个经常会遇到的关键术语:
Coroutine(协程)——一种可暂停、可恢复的执行单元,通过 spawn() 创建 await() ——等待某个协程的结果完成 Scope ——一种用于统一管理一组协程“生命周期”的机制,包括在某个协程失败时一次性取消全部协程 Cancellation(取消)——安全的协程取消机制,在设计上“天然可取消”,因此永远不会留下只执行到一半的数据
协程在底层究竟是如何工作的?
为了不只是在类比层面想象,TrueAsync 团队还构建了一个交互式可视化演示,精确展示引擎内部发生的一切:How Coroutines Work。
该演示展示了两个并排运行的协程:
Coroutine 1 ——处理用户数据,循环查询数据库中三个不同用户的数据 Coroutine 2 ——记录日志并发送通知,混合了数据库查询与写入 socket 的操作
这里有一个核心思想,也可以说是理解协程究竟是什么的最直观方式:两个协程高效地共享 CPU 时间。当 Coroutine 1 在等待某个数据库查询完成时(比如 15ms),CPU 并不会闲置——它会立即转而处理 Coroutine 2 的工作,反之亦然。这就是协作式多任务(cooperative multitasking):一个 PHP 进程、一个线程,却没有浪费的等待时间。
可以亲自打开这个演示,里面有一条可视化时间线,精确展示 CPU 何时在“真正工作”、何时在“等待”数据库或网络响应——此外还有具体数字,说明与顺序执行两个协程相比节省了多少时间。如果相比阅读理论,更擅长通过视觉来学习,那么这个演示值得一试。
项目目前已发展到什么程度?
这部分值得了解:True Async 不只是纸面上的提案。它已有一个真实可用的实现,现在就可以上手尝试。
以下是一些来自官方文档(true-async.github.io)的当前事实:
最新版本为 v0.8.4,标注为“Experimental Core(实验性核心)” 已经可用的稳定功能包括协程,以及 fread、file_get_contents、cURL、MySQL/PostgreSQL 连接等常见函数的非阻塞 I/O 内置针对 PDO 的连接池(connection pooling),因此不必担心在协程之间共享数据库连接 通过 spawn_thread() 提供原生线程支持,用于需要真正 CPU 并行、而不仅是 I/O 的工作 甚至还有一个直接运行在 PHP 进程内部的 HTTP/1.1、HTTP/2 与 HTTP/3 服务器,由 C 语言编写,无需单独的反向代理 可以通过官方安装程序或预构建的 Docker 镜像,为 PHP 8.5+ 安装该扩展——适合本地探索或业余项目,不过它仍处于实验阶段,不建议用于生产环境。
哪些 PHP 函数已经获得支持?
这正是 True Async 区别于典型“库叠加”方案的地方:他们已经让 70 多个标准 PHP 函数实现了在协程内调用时自动变为非阻塞。而在协程之外,这些函数的行为与之前完全一致——因此对现有代码没有任何破坏性变更。
部分已支持的类别如下:
DNS —— gethostbyname()、gethostbyaddr()、gethostbynamel() Database(数据库)——PDO MySQL 与 PgSQL(prepare()、exec()、execute()、fetch())、MySQLi、原生 PostgreSQL(pg_query()、pg_prepare() 等),外加 PDO 的自动连接池 cURL —— curl_exec()、curl_multi_exec()、curl_setopt()、curl_getinfo() 以及其他 cURL 函数 Sockets(套接字)——socket_create()、socket_connect()、socket_read()、socket_write()、socket_select() 等 File & Stream I/O(文件与流 I/O)——fopen()、fread()、fwrite()、file_get_contents()、file_put_contents()、flock()、stream_get_contents() 等 Stream Sockets(流套接字)——stream_socket_client()、stream_socket_server()、stream_select() Process Execution(进程执行)——proc_open()、exec()、shell_exec()、system()、passthru() Timers & Delays(定时器与延时)——sleep()、usleep()、time_nanosleep() Output Buffering(输出缓冲)——ob_start()、ob_flush()、ob_get_contents(),缓冲区按协程相互隔离
值得注意的一点是,部分函数有一些特殊注意事项。例如 flock() 天生是阻塞式系统调用——TrueAsync 的处理方式是将它卸载到线程池,这样在等待锁期间,其他协程仍可继续运行。还有一些函数仍被标记为“Not Yet Supported(尚未支持)”,比如目录操作(opendir()、mkdir()),以及 Oracle、SQLite 等少数 PDO 驱动——这主要是因为它们一直不是优先事项:本地文件元数据操作通常已经足够快,不需要再走异步。
完整的函数清单可查看官方 Supported Functions 页面。
目标锁定 PHP 8.6
在官方 php.watch 追踪页面上,True Async RFC 的目标版本(Target Version)标注为 PHP 8.6。这与项目自身的路线图相吻合——路线图计划于 2026 年 11 月发布稳定的 v1.0,与 PHP 8.6 的发布时间表一致。
几个值得注意的时间节点:
PHP 8.6 本身计划于 2026 年 11 月 19 日发布 PHP 8.6 Alpha 1 已于 2026 年 7 月 2 日发布 Beta 1 计划于 2026 年 8 月中旬前后发布
因此,在最终确定 True Async 在本轮 PHP 8.6 发布周期中将呈现的形态之前,还有几个月的时间。目前可以确定的是,团队正通过一个独立扩展积极开发和测试它,同时编写相当完善的文档与教程——从基础协程,到借助 Scope 实现结构化并发,再到从零构建 WebSocket 服务器,一应俱全。
True Async 究竟在 PHP 内部改变了什么?
比上面的代码类比更精确地说:根据官方文档,PHP TrueAsync 是一个通过在底层直接修改 Zend core、I/O 库、数据库库、socket 库以及其他各种函数,在 PHP 中实现原生异步的项目。
这种方案与大多数异步解决方案的区别在于:True Async 实现了一种无彩色函数(colored functions)的透明异步范式。“彩色函数”是 async/await 讨论中经常出现的术语——它描述的是这样一种情形:每个函数都必须被标记为“async”或“sync”,而一旦某个函数被标记为 async,所有调用它的函数也必须被标记为 async。这很混乱,还会把代码库一分为二。
True Async 则完全避免了这一点。由于它是透明的,因此能最大限度减少代码改动,并消除代码库被割裂的困境——一旦开始使用协程,使用的仍然是那些与往常完全相同的 PHP 函数,无需任何改动,至多只需极小的改动。
为更顺畅的开发流程提供 IDE 支持
如果已经在认真尝试 True Async,并正在使用 PhpStorm、PHPStan 或 Psalm,那么有一个包值得安装:true-async/ide-helper。
这个仅用于开发环境的包提供了自动补全、行内文档以及用于静态分析的 stub。覆盖范围相当全面——从异步核心,到 HTTP 服务器,再到 ClickHouse 客户端。
安装方法很简单,通过 Composer 即可:
composer require --dev true-async/ide-helper安装之后,只要在编辑器里输入 spawn() 或 await(),IDE 就会给出实际的参数与返回类型,而不是靠猜。这确实相当有用,尤其是在 API 仍在演进、偶尔会在不同版本之间发生变化的情况下。
那么,它真的会进入 PHP 8.6 吗?
坦白地说,这个问题目前还无法给出确定答案。目标版本在官方文档和 RFC 追踪器中都有明确记载,团队也正在积极构建并测试一个真实的实现——而不只是停留在纸面讨论。但与语言核心的大多数重大变更一样,确定性通常要到临近发布时才会出现。
现在能做的只有:持续关注它的进展,如果感兴趣就去试试这个扩展,并为 PHP 在不久的将来拥有原生并发模型的可能性做好准备。至于其他问题,就一起拭目以待,等 PHP 8.6 真正发布吧。
资料来源:TrueAsync 官方文档(true-async.github.io),包括 Introduction、Supported Functions、IDE Support 与 Interactive Coroutine Demo 等页面,以及 php.watch/rfcs/true_async 和官方 PHP 8.6 发布时间表页面——信息截至 2026 年 7 月。