Boost PHP Performance with AsyncIO: Fiber‑Based Asynchronous I/O Library

This guide introduces the PHP AsyncIO extension built on PHP Fiber and Workerman, explains its high‑performance features, shows how to install and quickly start with code examples for basic, concurrent, timeout‑controlled, and managed tasks, and provides a complete API reference and advanced usage tips.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Boost PHP Performance with AsyncIO: Fiber‑Based Asynchronous I/O Library

Overview

The AsyncIO extension provides high‑performance asynchronous I/O for PHP by combining native PHP Fiber support with the event‑driven Workerman framework. Its API mirrors Python's asyncio, enabling coroutine‑style programming in PHP.

Features

Fiber‑based – native coroutine support with minimal overhead.

Fully event‑driven – leverages Workerman’s non‑blocking architecture, eliminating polling.

Concurrency primitives – functions such as gather and wait_for for managing multiple tasks.

Precise timing – timer‑driven events with sub‑0.1 ms latency.

Robust exception handling – errors propagate through the async call chain.

Python‑like API – familiar function names and patterns for developers coming from asyncio.

Installation

composer require pfinalclub/asyncio

Requirements

PHP >= 8.1 (Fiber support required)

Workerman >= 4.1

Quick Start

Basic Example

<?php
require_once __DIR__.'/vendor/autoload.php';
use function PfinalClub\Asyncio\{run, sleep};

function hello_world(): mixed {
    echo "Hello
";
    sleep(1); // async sleep 1 second
    echo "World
";
    return "Done!";
}

$result = run(hello_world(...));
echo "Result: {$result}
";

Concurrent Tasks

<?php
use function PfinalClub\Asyncio\{run, create_task, gather, sleep};

function task1(): string {
    echo "Task 1 start
";
    sleep(2);
    echo "Task 1 done
";
    return "Result 1";
}

function task2(): string {
    echo "Task 2 start
";
    sleep(1);
    echo "Task 2 done
";
    return "Result 2";
}

function main(): array {
    $t1 = create_task(task1(...));
    $t2 = create_task(task2(...));
    $results = gather($t1, $t2);
    return $results; // ['Result 1', 'Result 2']
}

run(main(...));

Timeout Control

<?php
use function PfinalClub\Asyncio\{run, wait_for, sleep};
use PfinalClub\Asyncio\TimeoutException;

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

function main(): void {
    try {
        $result = wait_for(slow_task(...), 2.0); // wait at most 2 seconds
        echo "Result: {$result}
";
    } catch (TimeoutException $e) {
        echo "Task timed out: {$e->getMessage()}
";
    }
}

run(main(...));

Task Management

<?php
use function PfinalClub\Asyncio\{run, create_task, await, sleep};

function background_task(string $name): string {
    for ($i = 1; $i <= 5; $i++) {
        echo "{$name}: step {$i}
";
        sleep(0.5);
    }
    return "{$name} completed";
}

function main(): void {
    $task1 = create_task(fn() => background_task("TaskA"));
    $task2 = create_task(fn() => background_task("TaskB"));
    sleep(2);
    echo "Task1 done: " . ($task1->isDone() ? "yes" : "no") . "
";
    echo "Task2 done: " . ($task2->isDone() ? "yes" : "no") . "
";
    $result1 = await($task1);
    $result2 = await($task2);
    echo "{$result1}, {$result2}
";
}

run(main(...));

API Reference

Core Functions

run(callable $main): mixed

Runs the supplied coroutine until it completes and returns its result. This is the entry point for an AsyncIO program.

create_task(callable $callback, string $name = ''): Task

Creates a Task object and schedules it for immediate execution.

async(callable $callback, string $name = ''): Task

Alias of create_task, provided for naming consistency with typical async code.

sleep(float $seconds): void

Suspends the current coroutine for the given number of seconds. Must be called inside a Fiber context.

await(Task $task): mixed

Blocks until the specified task finishes and returns its result.

gather(Task ...$tasks): array

Runs multiple tasks concurrently and returns an array containing each task's result once all have completed.

wait_for(callable|Task $awaitable, float $timeout): mixed

Waits for a task or callable to finish; if the timeout expires a TimeoutException is thrown.

Event Loop

get_event_loop(): EventLoop

Retrieves the current event‑loop instance, allowing low‑level interaction if needed.

Task Class

isDone(): bool

– returns true if the task has completed. getResult(): mixed – obtains the task result; throws if the task is not finished. cancel(): bool – attempts to cancel the task and returns whether cancellation succeeded. addDoneCallback(callable $callback): void – registers a callback that runs when the task finishes.

Future Class

A Future represents a value that will become available later and can be fulfilled manually.

$future = create_future();
// later in the program
$future->setResult("result");
$result = await_future($future);

Advanced Usage

HTTP Client

<?php
use function PfinalClub\Asyncio\{run, create_task, gather};
use PfinalClub\Asyncio\Http\AsyncHttpClient;

function main(): void {
    $client = new AsyncHttpClient(['timeout' => 10]);
    // single request
    $response = $client->get('https://api.example.com/users');
    echo "Status: {$response->getStatusCode()}
";
    echo "Body: {$response->getBody()}
";
    // concurrent requests
    $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 $resp) {
        echo "Status: {$resp->getStatusCode()}
";
    }
}

run(main(...));

Monitoring Tool

<?php
use function PfinalClub\Asyncio\{run, create_task, gather};
use PfinalClub\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();
    echo $monitor->toJson();
}

run(main(...));

Debugger

<?php
use function PfinalClub\Asyncio\run;
use PfinalClub\Asyncio\Debug\AsyncioDebugger;

function main(): void {
    $debugger = AsyncioDebugger::getInstance();
    $debugger->enable();
    // ... your async code ...
    echo $debugger->visualizeCallChain();
    echo $debugger->report();
}

run(main(...));

Differences from v1.x (Generator‑based)

Signature change: function f(): \Generatorfunction f(): mixed Yield‑based sleep removed: yield sleep(1)sleep(1) Yielding a task replaced by explicit await: yield $task

await($task)
gather(...)

remains the same but now works with Task objects directly.

Run helper updated: run(generator())

run(callable)
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend DevelopmentPHPFiberasyncioWorkerman
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.