PHP 异步IO扩展包 AsyncIO v2.0.0 发布

概述

AsyncIO 基于 PHP FiberWorkerman 实现的高性能异步 IO 扩展包,提供类似 Python asyncio 的 API 和功能。

特性

  • 🚀 基于 PHP Fiber - 原生协程支持,性能卓越

  • 完全事件驱动 - 零轮询,充分利用 Workerman 高性能

  • 🎯 并发控制 - gather, wait_for, 任务管理

  • 精确定时 - < 0.1ms 延迟,Timer 事件驱动

  • 🛡️ 异常处理 - 完整的错误传播和处理

  • 📦 简洁API - 类似 Python asyncio 的使用体验

安装

复制代码
composer require pfinalclub/asyncio

要求

  • PHP >= 8.1 (需要 Fiber 支持)

  • Workerman >= 4.1

快速开始

基础示例

复制代码
<?php
require_once__DIR__ . '/vendor/autoload.php';

usefunctionPfinalClub\Asyncio\{run, sleep};

// 定义一个异步函数
function hello_world(): mixed
{
    echo"Hello\n";
    sleep(1); // 异步睡眠 1 秒
    echo"World\n";
    return"Done!";
}

// 运行主函数
$result = run(hello_world(...));
echo"Result: {$result}\n";

并发任务

复制代码
<?php
usefunctionPfinalClub\Asyncio\{run, create_task, gather, sleep};

function task1(): string
{
    echo"Task 1 开始\n";
    sleep(2);
    echo"Task 1 完成\n";
    return"结果 1";
}

function task2(): string
{
    echo"Task 2 开始\n";
    sleep(1);
    echo"Task 2 完成\n";
    return"结果 2";
}

function main(): array
{
    // 创建任务
    $t1 = create_task(task1(...));
    $t2 = create_task(task2(...));
    
    // 并发等待所有任务完成
    $results = gather($t1, $t2);
    
    return $results; // ['结果 1', '结果 2']
}

run(main(...));

超时控制

复制代码
<?php
usefunctionPfinalClub\Asyncio\{run, wait_for, sleep};
usePfinalClub\Asyncio\TimeoutException;

function slow_task(): string
{
    sleep(5);
    return"完成";
}

function main(): void
{
    try {
        // 最多等待 2 秒
        $result = wait_for(slow_task(...), 2.0);
        echo"结果: {$result}\n";
    } catch (TimeoutException $e) {
        echo"任务超时: {$e->getMessage()}\n";
    }
}

run(main(...));

任务管理

复制代码
<?php
usefunctionPfinalClub\Asyncio\{run, create_task, await, sleep};

function background_task(string $name): string
{
    for ($i = 1; $i <= 5; $i++) {
        echo"{$name}: 步骤 {$i}\n";
        sleep(0.5);
    }
    return"{$name} 完成";
}

function main(): void
{
    // 创建多个后台任务
    $task1 = create_task(fn() => background_task("任务A"));
    $task2 = create_task(fn() => background_task("任务B"));
    
    // 等待一段时间
    sleep(2);
    
    // 检查任务状态
    echo"任务1 完成: " . ($task1->isDone() ? "是" : "否") . "\n";
    echo"任务2 完成: " . ($task2->isDone() ? "是" : "否") . "\n";
    
    // 等待任务完成
    $result1 = await($task1);
    $result2 = await($task2);
    
    echo"{$result1}, {$result2}\n";
}

run(main(...));

API 参考

核心函数

run(callable $main): mixed

运行主函数直到完成并返回结果。这是程序的主入口点。

复制代码
$result = run(my_function(...));
create_task(callable $callback, string $name = ''): Task

创建并调度一个任务,立即开始执行。

复制代码
$task = create_task(my_function(...), 'my-task');
async(callable $callback, string $name = ''): Task

create_task 的别名,更符合异步编程习惯。

复制代码
$task = async(my_function(...));
sleep(float $seconds): void

异步睡眠指定的秒数。必须在 Fiber 上下文中调用。

复制代码
sleep(1.5); // 睡眠 1.5 秒
await(Task $task): mixed

等待任务完成并返回结果。

复制代码
$result = await($task);
gather(Task ...$tasks): array

并发运行多个任务并等待它们全部完成。

复制代码
$results = gather($task1, $task2, $task3);
wait_for(callable|Task $awaitable, float $timeout): mixed

等待任务完成,如果超时则抛出 TimeoutException。

复制代码
try {
    $result = wait_for(my_task(...), 5.0);
} catch (TimeoutException $e) {
    echo "超时!\n";
}

事件循环

get_event_loop(): EventLoop

获取当前事件循环实例。

复制代码
$loop = get_event_loop();

Task 类

isDone(): bool

检查任务是否已完成。

getResult(): mixed

获取任务结果(如果任务未完成会抛出异常)。

cancel(): bool

取消任务。

addDoneCallback(callable $callback): void

添加任务完成时的回调。

Future 类

Future 表示一个未来的结果,可以手动设置。

复制代码
$future = create_future();

// 在某处设置结果
$future->setResult("结果");

// 等待结果
$result = await_future($future);

高级用法

HTTP 客户端

复制代码
use functionPfinalClub\Asyncio\{run, create_task, gather};
usePfinalClub\Asyncio\Http\AsyncHttpClient;

function main(): void
{
    $client = new AsyncHttpClient(['timeout' => 10]);
    
    // 单个请求
    $response = $client->get('https://api.example.com/users');
    echo"Status: {$response->getStatusCode()}\n";
    echo"Body: {$response->getBody()}\n";
    
    // 并发请求
    $task1 = create_task(fn() => $client->get('https://api.example.com/users/1'));
    $task2 = create_task(fn() => $client->get('https://api.example.com/users/2'));
    $task3 = create_task(fn() => $client->get('https://api.example.com/users/3'));
    
    $responses = gather($task1, $task2, $task3);
    
    foreach ($responses as $response) {
        echo"Status: {$response->getStatusCode()}\n";
    }
}

run(main(...));

监控工具

复制代码
use functionPfinalClub\Asyncio\{run, create_task, gather};
usePfinalClub\Asyncio\Monitor\AsyncioMonitor;

function main(): void
{
    $monitor = AsyncioMonitor::getInstance();
    
    // 创建任务
    $tasks = [
        create_task(fn() => my_task1()),
        create_task(fn() => my_task2()),
    ];
    
    gather(...$tasks);
    
    // 显示监控报告
    echo $monitor->report();
    
    // 导出 JSON
    echo $monitor->toJson();
}

run(main(...));

调试器

复制代码
use functionPfinalClub\Asyncio\run;
usePfinalClub\Asyncio\Debug\AsyncioDebugger;

function main(): void
{
    $debugger = AsyncioDebugger::getInstance();
    $debugger->enable();
    
    // 你的代码...
    
    // 显示调用链
    echo $debugger->visualizeCallChain();
    
    // 显示报告
    echo $debugger->report();
}

run(main(...));

与 v1.x 的区别

主要变更

v1.x (Generator) v2.0 (Fiber)
function f(): \Generator function f(): mixed
yield sleep(1) sleep(1)
yield $task await($task)
yield gather(...) gather(...)
run(generator()) run(callable)
相关推荐
BingoGo17 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack17 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
QQ5110082854 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
WeiXin_DZbishe4 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5