Introduction to Asynchronous Programming in PHP
\n\nTraditional PHP works synchronously: each operation is executed sequentially. If a script needs to send an HTTP request or read a file, it waits for the operation to complete, blocking the execution of all code. For high-load web applications, this becomes a bottleneck. Asynchronous programming solves this problem by allowing multiple tasks to be executed simultaneously without blocking the main thread.
\n\nIn this guide, we will break down how asynchrony works in PHP, what tools are available, and how to use them in practice. You will learn about generators, the ReactPHP and Swoole libraries, as well as the new capabilities of PHP 8.1 — Fiber.
\n\nFundamentals of Asynchronous Programming
\n\nWhat is Asynchrony and Why is it Needed?
\n\nImagine you are making breakfast. The synchronous approach: you put the kettle on, wait for it to boil, then start frying eggs. The asynchronous approach: you put the kettle on and, while the water is heating, you prepare the scrambled eggs in parallel. In PHP, this means that instead of waiting for a response from a database or an external API, you can execute other code.
\n\nMain advantages of the asynchronous approach:
\n- \n
- Increased performance for I/O operations (network, disks, databases) \n
- Server resource savings — fewer threads handle more requests \n
- Ability to create real-time applications (chats, notifications, streaming) \n
The Problem with Synchronous Code
\n\nConsider a classic example: fetching data from two remote APIs. Synchronous code will execute sequentially:
\n\n<?php\nfunction fetchData($url) {\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n $result = curl_exec($ch); // Blocking during the request\n curl_close($ch);\n return $result;\n}\n\n$start = microtime(true);\n$data1 = fetchData('https://api.example.com/users');\n$data2 = fetchData('https://api.example.com/posts');\necho "Time: " . (microtime(true) - $start);\n?>\n\nIf each request takes 2 seconds, the total execution time will be 4 seconds, even though we could have executed the requests in parallel.
\n\nTools for Asynchrony in PHP
\n\n1. Generators (yield) — Lightweight Asynchrony
\n\nGenerators appeared in PHP 5.5 and allow you to create functions that can pause their execution and return control to the calling code. This is the foundation for creating coroutines.
\n\n<?php\nfunction generator() {\n echo "Start of generator\\n";\n yield 1;\n echo "After first yield\\n";\n yield 2;\n echo "End\\n";\n}\n\n$gen = generator();\nforeach ($gen as $value) {\n echo "Received: $value\\n";\n}\n?>\n\nGenerators can be used to organize non-blocking operations in conjunction with an event loop. However, this is not enough for full-fledged asynchrony — a library is needed.
\n\n2. ReactPHP — Event-Driven Library
\n\nReactPHP is a popular library for asynchronous programming. It provides an Event Loop, non-blocking sockets, an HTTP client, and a server. Installation via Composer:
\n\ncomposer require react/event-loop react/http\n\nExample of an asynchronous HTTP request:
\n\n<?php\nrequire 'vendor/autoload.php';\n\nuse React\\EventLoop\\Factory;\nuse React\\HttpClient\\Client;\nuse React\\HttpClient\\Response;\n\n$loop = Factory::create();\n$client = new Client($loop);\n\n$request = $client->request('GET', 'https://api.example.com/data');\n$request->on('response', function (Response $response) {\n $response->on('data', function ($chunk) {\n echo "Received chunk: " . strlen($chunk) . " bytes\\n";\n });\n $response->on('end', function () {\n echo "Request completed\\n";\n });\n});\n$request->end();\n\necho "Request sent, waiting...\\n";\n$loop->run();\n?