原生70+ 函数自动非阻塞
写在前面|如果 PHP 从此不再「干等」,会发生什么?一个叫 True Async 的项目,正试图把协程与非阻塞 I/O 直接写进 PHP 内核,目标版本就是 PHP 8.6。这不是又一个框架,而是一次内核级改造。今天这篇文章,带你把它看明白。
—— 你的 PHP 技术观察员 Tinywan
True Async 项目计划将协程与非阻塞 I/O 直接内置到 PHP 内核中,目标落地版本为 PHP 8.6。目前该项目已推出可运行的实验性扩展,迭代到 v0.9.3(2026 年 8 月 13 日发布),支持超过 70 个原生函数、数据库连接池,甚至内置了独立 HTTP 服务器。
在此之前,PHP 应用若要实现并发能力——比如同时调用多个 API、在读取文件的同时执行数据库查询——只能依赖 AMPHP、ReactPHP、Swoole 等第三方扩展或框架。而 True Async 走了一条完全不同的路径:它直接在 PHP 引擎层面实现了一套并发模型。目前该提案的 RFC 已收录于 PHP.Watch 的版本规划中,目标随 PHP 8.6 正式进入内核。
01为什么需要异步?
传统 PHP (FPM) 的工作方式
图 1 · 传统 PHP-FPM:每个请求独享一个进程,处理完即销毁
如果将 PHP 服务器应用程序比作一家餐厅,它可能会被认为是一家高档餐厅,每张桌子都有专属服务员。
每个新的服务器请求都由独立的 PHP 虚拟机、进程或线程处理,处理完成后状态被销毁。这就相当于一个服务员服务完一张桌子后就被解雇或者被清除了记忆。
这种模型有一个优势:如果发生 PHP 错误、内存泄漏、忘记关闭的数据库连接——不会影响其他请求。每个请求都是隔离的。这意味着开发更简单,调试更简单,并且具有很高的容错性。
近年来,PHP 社区一直在尝试引入有状态模型,即单个 PHP 虚拟机可以服务多个请求,在请求之间保持状态。例如,Laravel Octane 项目使用 Swoole 或 RoadRunner,通过在请求之间保持状态来实现更好的性能。但这远非可能性的极限。
每次点单后就解雇服务员代价太高。因为菜肴在厨房准备很慢,服务员大部分时间都在等待。PHP-FPM 也是如此:PHP 虚拟机处于空闲状态。有更多的上下文切换、更多创建和销毁进程或线程的开销,以及更多的资源消耗。
PHP · 串行写法
// 传统 PHP-FPM:串行等待
$user = file_get_contents('https://api/user/123'); // 站着等 300ms
$orders = $db->query('SELECT * FROM orders'); // 站着等 150ms
$balance = file_get_contents('https://api/balance'); // 站着等 200ms
// 花费:650ms 纯等待
// CPU 空闲。内存空闲。一切都在等待。
并发:一个服务员,多张桌子
图 2 · 并发模型:等待间隙被用来服务其他协程
由于厨房不能立即准备好菜肴,而服务员在准备期间有空闲时间,就有机会处理多位顾客的订单。
这个方案可以非常灵活地运作:1 号桌点了三道菜,2 号桌点了两道菜。服务员先给 1 号桌上第一道菜,然后给 2 号桌上第一道菜;或者也许他设法给第一桌上了两道菜,给第二桌上了一道。或者反过来!
这就是并发:在不同的逻辑执行线程之间共享单个资源(CPU),这些逻辑执行线程被称为协程。
PHP · 并发写法
// 并发写法:三个请求同时出发
use function Async\spawn;
use function Async\await;
// "并发"启动所有三个请求
$userTask = spawn(file_get_contents(...), 'https://api/user/123');
$ordersTask = spawn($db->query(...), 'SELECT * FROM orders');
$balanceTask = spawn(file_get_contents(...), 'https://api/balance');
// 当一个请求在等待响应时,我们处理其他的!
$user = await($userTask);
$orders = await($ordersTask);
$balance = await($balanceTask);
// 花费:300ms(最慢请求的时间)
划重点|串行 650ms 的活儿,并发只要 300ms。但问题来了:写成这样,代码还简单吗?True Async 给出的答案是——几乎不用改写法。
02同步编写,异步运行
True Async 最打动人的地方,是它对开发者的侵入性降到了最低。
如果你写过 JavaScript 或 Python 的 async/await,一定熟悉「函数染色」的痛点:一旦某个函数变成异步,所有调用它的函数都要加上 async,整条调用链都要跟着改。同步代码和异步代码是两个世界,几乎没法无痛混用。
它本质是单进程单线程的协作式多任务:I/O 等待时自动调度切换,CPU 密集时顺序执行,既兼顾了并发性能,又保留了 PHP 一贯的简单性。
而实现这一切,只需要几个极简的 API:
PHP · 三个任务并发跑
// 代码还是同步的味道
<?php
// 同时发起三个异步任务:网络请求、数据库查询、接口调用
$page = spawn(fn() => file_get_contents($url));
$rows = spawn(fn() => $pdo->query($sql)->fetchAll());
$stats = spawn(fn() => file_get_contents($api));
// 等待全部完成,2秒超时自动取消
[$html, $data, $meta] = await_all_or_fail(
[$page, $rows, $stats],
timeout(2000)
);
三个原本串行的 I/O 操作,总耗时从三者之和变成了最慢一个的耗时,而代码几乎还是熟悉的同步写法。
03核心 API 设计
整套 API 围绕四个核心概念设计,用法简洁直观:
▸spawn():创建一个协程(可暂停、可恢复的执行单元)
▸await():等待单个协程执行完成并获取结果
▸Scope 作用域:管理一组协程的生命周期;当其中一个协程失败时,可批量取消全部协程
▸安全取消机制:协程取消时不会产生半成品数据,保证状态一致性
举个典型场景:将三个原本串行执行、各耗时 1 秒的操作封装进协程,通过 await_all_or_fail() 配合超时统一收集结果,它们就会并发执行——总耗时将接近最慢单任务的耗时,而非三者之和。
说明|你可能会问:这和 JS 的 async/await 有什么区别?区别正是它最大的卖点。
04核心优势:没有「函数染色」问题
和 JavaScript、Python 中的 async/await 不同,True Async 刻意避免了「函数染色」问题:
▸ 没有 async 关键字,普通同步代码无需修改就能直接在协程中运行
▸ 这一特性是通过修改 Zend 内核、I/O 层、数据库层与 Socket 层共同实现的
从本质上讲,它属于协作式多任务模型:单进程、单线程运行,当当前协程进入 I/O 等待时,CPU 会自动切换到另一个协程继续执行。项目官网提供了交互式可视化演示:一个协程处理用户数据,另一个协程负责日志与通知发送,两者交替共享 CPU 时间片。
05不止是草案:已有可运行实现
这个项目并非停留在纸面设计。当前 v0.9.3 版本(标记为「实验性内核」)已经包含大量可用能力:
▸ 完整可运行的协程机制
▸ 非阻塞 I/O:覆盖 fread、file_get_contents、cURL 等常用函数
▸ 内置 PDO 数据库连接池
▸ 通过 spawn_thread() 支持原生线程,用于 CPU 密集型并行计算
▸ 纯 C 实现的 HTTP/1.1、HTTP/2、HTTP/3 服务器,可直接在 PHP 进程中运行,无需反向代理
▸框架适配层(v0.9.0 起):已提供 Symfony 适配器与迁移指南,让现有框架项目平滑接入
该扩展目前支持 PHP 8.5 及以上版本,可通过官方安装器或预构建 Docker 镜像安装;仍处于实验阶段,不建议在生产环境使用。
06覆盖范围:70+ 原生函数自动非阻塞
已有超过 70 个 PHP 标准函数完成适配:它们在协程内会自动切换为非阻塞模式,在协程外则保持原有行为完全不变——对现有代码零破坏性。
已覆盖的功能范围:
▸ DNS 解析:gethostbyname() 及相关函数
▸ 数据库:PDO MySQL / PgSQL、MySQLi、原生 PostgreSQL 驱动
▸ 网络:cURL、Socket、流套接字
▸ 文件与流 I/O:fopen()、fread()、file_put_contents()、flock()
▸ 进程执行:proc_open()、exec()、shell_exec()
▸ 定时器:sleep()、usleep()
▸ 输出缓冲:每个协程拥有独立隔离的缓冲区
其中,flock() 这类天生阻塞的系统调用会被转交给线程池执行,确保其他协程可以继续运行。
暂未支持的功能:
▸opendir()、mkdir() 等目录操作
▸ Oracle、SQLite 等少数 PDO 驱动
官方将这类功能列为低优先级,因为本地元数据操作通常速度很快,对并发收益影响不大。
写在最后之前|功能清单已经够长,那到底什么时候能用上?
07路线图与落地时间
项目规划在 2026 年 11 月发布稳定 v1.0 版本,与 PHP 8.6 的发布节奏对齐:
1PHP 8.6 Alpha 1:2026 年 7 月 2 日已发布2PHP 8.6 Beta 1:预计 2026 年 8 月中旬3PHP 8.6 正式版:计划 2026 年 11 月 19 日该特性最终是否能进入 PHP 8.6 正式版目前尚无定论;按照历史经验,这类大规模内核改动,通常要到发布临近阶段才能最终确认。
08开发者配套工具
对于希望提前体验的开发者,项目提供了专属 Composer 开发包 true-async/ide-helper,为 PhpStorm、PHPStan、Psalm 提供自动补全、内联文档与函数桩文件,覆盖异步内核、HTTP 服务器、ClickHouse 客户端等全部能力——在 API 仍频繁变动的阶段,这对开发体验提升非常明显。
写在最后|PHP 的每一次内核进化,都会重塑它的适用边界。True Async 能否随 8.6 正式落地还悬而未决,但方向已经清晰:PHP 正在把「简单」延伸到并发时代。值得每个 PHP 开发者保持关注。
—— 如果这篇对你有帮助 ——
点赞 · 在看 · 转发,是对我最大的支持
关注我,第一时间见证 PHP 8.6 的每一个关键时刻