frankenphp 通过 fiber 和 trueasync 实现异步,需启用 worker 模式并配合异步原语;fiber 轻量但需避免阻塞函数,trueasync 提供更完整协程生态与连接池;务必正确配置 docker、禁用 opcache 预加载、隔离全局状态。

支持,FrankenPHP 本身不直接提供类似 async/await 的语法糖,但通过内置的 PHP Fiber(纤程) 和与 TrueAsync 生态的深度集成,可以实现真正轻量、非阻塞的异步任务处理。关键在于运行模式和代码写法的配合——必须启用 worker 模式,并在 PHP 代码中主动使用 Fiber 或 TrueAsync 提供的协程原语。
Fiber 原生异步:零依赖、开箱即用
FrankenPHP 在 worker 模式下原生支持 PHP 8.1+ 的 Fiber 类,适合简单并发场景,比如并行调用多个 API:
- 每个
Fiber是一个可挂起/恢复的轻量执行单元,不占用 OS 线程 - 必须在
frankenphp:franken命令启动的 worker 模式下运行,classic 模式无效 - 不能在 Fiber 内直接使用阻塞函数(如
sleep()、file_get_contents()),需改用 FrankenPHP 提供的异步替代(如frankenphp\http_client)或封装为可挂起操作
示例:同时请求两个外部接口
<?php $userFiber = new Fiber(function () {
$client = new frankenphp\HttpClient();
return $client->get('https://api.example.com/users/1');
});
$postFiber = new Fiber(function () {
$client = new frankenphp\HttpClient();
return $client->get('https://api.example.com/posts/5');
});
$userFiber->start();
$postFiber->start();
$user = $userFiber->getReturn();
$post = $postFiber->getReturn();
echo "User: " . $user['name'] . ", Post: " . $post['title'];
?>
TrueAsync 协程生态:更完整、生产就绪
若需数据库连接池、定时任务、后台作业等能力,推荐搭配 trueasync/php-true-async 运行时(官方推荐镜像:trueasync/php-true-async:latest-frankenphp):
- 提供
spawn()启动后台协程,await()等待结果,语义更清晰 - 已内置 PostgreSQL/MySQL 连接池,支持
await $pool->query(...) - 可结合 Laravel 的
async:frankenArtisan 命令启动 worker
示例:异步查询数据库 + 发送通知
<?php use TrueAsync\Future;
// 启动两个异步任务
$userFuture = spawn(fn() => DB::table('users')->where('id', 1)->first());
$notifyFuture = spawn(fn() => sendSlackAlert('New user signed up'));
// 并发等待
[$user, $result] = await_all([$userFuture, $notifyFuture]);
if ($user) {
echo "Loaded user: {$user->name}";
}
?>
编写要点与避坑提醒
不是所有 PHP 代码都能“自动变异步”,以下细节决定成败:
-
Docker 配置必须匹配:使用
trueasync/php-true-async:latest-frankenphp镜像,且command设为php artisan async:franken --workers=2 -
禁用 OPcache 预加载干扰:worker 模式下预加载可能锁定类定义,建议关闭或谨慎配置
opcache.preload -
避免全局状态污染:Fiber 间不共享变量,
static属性、全局数组、未重置的单例在并发下可能出错 -
错误不能跨 Fiber 传播:需在每个 Fiber 内部
try/catch,或用Future::catch()统一处理
验证是否真异步运行
最简单的确认方式是观察日志时间戳或使用 microtime(true) 对比:
- 串行执行两个 500ms 的 HTTP 请求,总耗时应接近 1000ms
- 用 Fiber 或
spawn()并行执行,总耗时应接近 500ms - 若耗时仍为 1000ms+,说明未进入异步路径(常见原因:没启 worker 模式、用了阻塞函数、镜像版本不对)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











