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

概述

AsyncIO 基于 PHP Fiber 和 Workerman 实现的高性能异步 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)
相关推荐
爱和冰阔落15 小时前
【Linux网络】JsonCpp 怎么实现序列化?从 Request/Response 到网络计算器消息设计
linux·运维·网络·php
eggwyw15 小时前
PHP8.5怎么用ffmpeg提取视频里的字幕轨道
开发语言·php
我叫黑大帅1 天前
PHP 常驻 Worker 中 MySQL 连接中断问题报告
后端·面试·php
国科安芯1 天前
人在回路中的总线:商业空间站环境控制与生命保障系统CANFD网络的可靠性与功能安全
网络·嵌入式硬件·安全·架构·php·抗辐射
码途行者2 天前
网站的SQL 注入:从攻击原理到防御措施
开发语言·sql·php
fish_zzzz2 天前
笔记-论数据结构2
1024程序员节
老秦包你会2 天前
计算机网络第二课 ----Socket(套接字)编程预备
开发语言·计算机网络·php
迪康coolmu2 天前
出差终端数据安全落地实战:基于迪康端点安全一体化管理系统的四道防线实践
运维·服务器·经验分享·笔记·其他·安全·php
普通人62 天前
PHP文件读写完全指南
开发语言·php·1024程序员节
Martina_03212 天前
AI生成3D场景从白模换成精模后镜头全偏了?用6步检查单位、枢轴与层级替换
图像处理·人工智能·3d·ai·自然语言处理·材质·1024程序员节