All skills
Skillintermediate

Async PHP Patterns

```php <?php

Claude Code Knowledge Pack7/10/2026

Overview

Async PHP Patterns

Swoole HTTP Server

<?php

declare(strict_types=1);

use Swoole\\HTTP\\Server;
use Swoole\\HTTP\\Request;
use Swoole\\HTTP\\Response;

$server = new Server('0.0.0.0', 9501);

$server->set([
    'worker_num' => 4,
    'max_request' => 10000,
    'task_worker_num' => 2,
    'enable_coroutine' => true,
]);

$server->on('start', function (Server $server) {
    echo "Swoole HTTP server started at http://0.0.0.0:9501\
";
});

$server->on('request', function (Request $request, Response $response) {
    $response->header('Content-Type', 'application/json');

    match ($request->server['request_uri']) {
        '/api/users' => handleUsers($request, $response),
        '/api/health' => $response->end(json_encode(['status' => 'healthy'])),
        default => $response->status(404)->end(json_encode(['error' => 'Not found'])),
    };
});

function handleUsers(Request $request, Response $response): void
{
    // Coroutine for concurrent DB queries
    go(function () use ($response) {
        $users = queryDatabase('SELECT * FROM users LIMIT 10');
        $response->end(json_encode(['data' => $users]));
    });
}

$server->start();

Swoole Coroutines

<?php

declare(strict_types=1);

use Swoole\\Coroutine;
use Swoole\\Coroutine\\Http\\Client;

// Concurrent HTTP requests
Coroutine\\run(function () {
    $results = [];

    // Create multiple coroutines
    $wg = new Coroutine\\WaitGroup();

    $urls = [
        'https://api.example.com/users',
        'https://api.example.com/posts',
        'https://api.example.com/comments',
    ];

    foreach ($urls as $url) {
        $wg->add();
        go(function () use ($url, &$results, $wg) {
            $client = new Client(parse_url($url, PHP_URL_HOST), 443, true);
            $client->set(['timeout' => 5]);
            $client->get(parse_url($url, PHP_URL_PATH));

            $results[$url] = [
                'status' => $client->statusCode,
                'body' => $client->body,
            ];

            $client->close();
            $wg->done();
        });
    }

    $wg->wait();

    print_r($results);
});

Swoole Async MySQL

<?php

declare(strict_types=1);

use Swoole\\Coroutine;
use Swoole\\Coroutine\\MySQL;

Coroutine\\run(function () {
    $mysql = new MySQL();

    $connected = $mysql->connect([
        'host' => '127.0.0.1',
        'port' => 3306,
        'user' => 'root',
        'password' => 'password',
        'database' => 'test',
    ]);

    if (!$connected) {
        throw new \\RuntimeException($mysql->connect_error);
    }

    // Async query
    $result = $mysql->query('SELECT * FROM users WHERE active = 1');

    foreach ($result as $row) {
        echo "User: {$row['name']}\
";
    }

    // Prepared statements
    $stmt = $mysql->prepare('SELECT * FROM users WHERE id = ?');
    $stmt->execute([42]);
    $user = $stmt->fetchAll();

    $mysql->close();
});

Swoole Channel (Communication)

<?php

declare(strict_types=1);

use Swoole\\Coroutine;
use Swoole\\Coroutine\\Channel;

Coroutine\\run(function () {
    $channel = new Channel(10); // Buffer size: 10

    // Producer
    go(function () use ($channel) {
        for ($i = 1; $i <= 5; $i++) {
            $channel->push("Task {$i}");
            echo "Produced: Task {$i}\
";
            Coroutine::sleep(0.5);
        }
        $channel->close();
    });

    // Consumer
    go(function () use ($channel) {
        while (true) {
            $task = $channel->pop();
            if ($task === false && $channel->errCode === SWOOLE_CHANNEL_CLOSED) {
                break;
            }
            echo "Consumed: {$task}\
";
            Coroutine::sleep(1);
        }
    });
});

ReactPHP Event Loop

<?php

declare(strict_types=1);

require 'vendor/autoload.php';

use React\\EventLoop\\Loop;
use React\\Http\\Message\\Response;
use Psr\\Http\\Message\\ServerRequestInterface;

// HTTP Server
$server = new React\\Http\\HttpServer(function (ServerRequestInterface $request) {
    return new Response(
        200,
        ['Content-Type' => 'application/json'],
        json_encode([
            'method' => $request->getMethod(),
            'uri' => (string) $request->getUri(),
            'timestamp' => time(),
        ])
    );
});

$socket = new React\\Socket\\SocketServer('0.0.0.0:8080');
$server->listen($socket);

echo "Server running at http://0.0.0.0:8080\
";

// Periodic timer
Loop::addPeriodicTimer(5.0, function () {
    echo "Heartbeat: " . date('H:i:s') . "\
";
});

// One-time timer
Loop::addTimer(10.0, function () {
    echo "This runs once after 10 seconds\
";
});

ReactPHP Async MySQL

<?php

declare(strict_types=1);

require 'vendor/autoload.php';

use React\\MySQL\\Factory;
use React\\MySQL\\QueryResult;

$factory = new Factory();

$connection = $factory->createLazyConnection('root:password@localhost/database');

$connection->query('SELECT * FROM users WHERE active = 1')
    ->then(
        function (QueryResult $result) {
            echo "Found " . count($result->resultRows) . " users\
";
            foreach ($result->resultRows as $row) {
                echo "User: {$row['name']}\
";
            }
        },
        function (\\Exception $error) {
            echo "Error: " . $error->getMessage() . "\
";
        }
    );

// Prepared statements
$connection->query('SELECT * FROM users WHERE id = ?', [42])
    ->then(function (QueryResult $result) {
        $user = $result->resultRows[0] ?? null;
        var_dump($user);
    });

ReactPHP Promises

<?php

declare(strict_types=1);

use React\\Promise\\Promise;
use React\\Promise\\Deferred;
use function React\\Promise\\all;

// Creating promises
function fetchUser(int $id): Promise
{
    $deferred = new Deferred();

    // Simulate async operation
    Loop::addTimer(1.0, function () use ($deferred, $id) {
        $deferred->resolve([
            'id' => $id,
            'name' => "User {$id}",
        ]);
    });

    return $deferred->promise();
}

// Using promises
fetchUser(42)
    ->then(function ($user) {
        echo "Got user: {$user['name']}\
";
        return fetchUserPosts($user['id']);
    })
    ->then(function ($posts) {
        echo "Got " . count($posts) . " posts\
";
    })
    ->catch(function (\\Exception $error) {
        echo "Error: " . $error->getMessage() . "\
";
    });

// Parallel promises
all([
    fetchUser(1),
    fetchUser(2),
    fetchUser(3),
])->then(function ($users) {
    echo "Fetched " . count($users) . " users\
";
});

PHP Fibers (Native PHP 8.1+)

<?php

declare(strict_types=1);

// Simple async function using fibers
function async(callable $callback): Fiber
{
    return new Fiber($callback);
}

function await(Fiber $fiber): mixed
{
    if (!$fiber->isStarted()) {
        return $fiber->start();
    }
    if ($fiber->isTerminated()) {
        return $fiber->getReturn();
    }
    return $fiber->resume();
}

// Simulate async I/O
function fetchData(string $url): Fiber
{
    return async(function () use ($url) {
        echo "Fetching: {$url}\
";
        Fiber::suspend('pending');

        // Simulate network delay
        sleep(1);

        return "Data from {$url}";
    });
}

// Usage
$fiber1 = fetchData('https://api.example.com/users');
$fiber2 = fetchData('https://api.example.com/posts');

await($fiber1);
await($fiber2);

$result1 = await($fiber1);
$result2 = await($fiber2);

echo "{$result1}\
";
echo "{$result2}\
";

Amphp Framework

<?php

declare(strict_types=1);

require 'vendor/autoload.php';

use Amp\\Http\\Server\\HttpServer;
use Amp\\Http\\Server\\Request;
use Amp\\Http\\Server\\Response;
use Amp\\Http\\Server\\Router;
use Amp\\Socket\\Server as SocketServer;
use function Amp\\async;
use function Amp\\Future\\await;

// HTTP Server with Amphp
$router = new Router();

$router->addRoute('GET', '/api/users', function (Request $request): Response {
    // Concurrent database queries
    $users = await([
        async(fn() => queryUsers()),
        async(fn() => queryUserStats()),
    ]);

    return new Response(
        status: 200,
        headers: ['content-type' => 'application/json'],
        body: json_encode(['users' => $users[0], 'stats' => $users[1]]),
    );
});

$server = new HttpServer(
    servers: [SocketServer::listen('0.0.0.0:8080')],
    requestHandler: $router,
);

$server->start();

Quick Reference

TechnologyUse CasePerformance
SwooleHigh-performance servers, WebSocketsVery High
ReactPHPEvent-driven apps, real-timeHigh
AmphpModern async frameworkHigh
FibersNative async (PHP 8.1+)Medium
GeneratorsSimple async patternsMedium
FeatureSwooleReactPHPAmphp
CoroutinesYesNo (Promises)Yes (Fibers)
HTTP ServerBuilt-inVia packageVia package
WebSocketsBuilt-inVia packageVia package
ExtensionRequiredNot requiredNot required
Learning CurveMediumLowMedium