PHP异步编程完全指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP 异步编程简介

传统上,PHP 被认为是一种同步语言:每个请求按顺序执行,在操作完成之前(例如数据库查询或 API 请求)会阻塞执行。然而,随着 Web 应用程序性能要求的提高,PHP 中的异步编程变得越来越受欢迎。异步代码允许同时执行多个任务,无需等待每个任务完成,这大大加快了请求处理速度并减轻了服务器负载。

在本指南中,我们将介绍 PHP 中异步编程的基本概念,探讨流行的库(ReactPHP、Amp),以及现代语言特性——Fiber 和生成器。

异步基础:事件循环和非阻塞 I/O

任何异步方法的基础都是 Event Loop(事件循环)。这是一个无限循环,检查是否发生了任何事件(例如,HTTP 请求完成或文件读取完成)。如果事件发生,则执行相应的处理程序。同时,主线程不会被阻塞——它可以切换到另一个任务。

非阻塞 I/O(Non-blocking I/O) 是关键原则。在同步代码中,调用 file_get_contents() 会阻塞脚本执行,直到文件完全加载。在异步模式下,您启动一个操作并继续执行其他代码,结果通过回调或 Promise 返回。

示例:同步请求 vs 异步请求

// 同步代码(阻塞)
$start = microtime(true);
$data1 = file_get_contents('http://example.com/api1');
$data2 = file_get_contents('http://example.com/api2');
echo "执行时间: " . (microtime(true) - $start) . " 秒"; // ~2 秒(如果每个请求 1 秒)

// 异步代码(ReactPHP)
$loop = React\\EventLoop\\Factory::create();
$client = new React\\Http\\Browser($loop);

$promise1 = $client->get('http://example.com/api1');
$promise2 = $client->get('http://example.com/api2');

$promise1->then(function ($response) {
    echo "收到响应 1";
});
$promise2->then(function ($response) {
    echo "收到响应 2";
});

$loop->run();
// 执行时间 ~1 秒(请求并行执行)

PHP 异步编程库

目前,两个最流行的库是 ReactPHP 和 Amp。两者都提供 Event Loop、Promise 以及用于处理 HTTP、套接字和文件系统的现成组件。

ReactPHP

ReactPHP 是一个成熟的库,自 2012 年以来一直存在。它提供对事件循环的低级访问以及许多组件:react/socket、react/http、react/dns 等。

// ReactPHP HTTP 服务器示例
$loop = React\\EventLoop\\Factory::create();
$server = new React\\Http\\Server($loop, function (Psr\\Http\\Message\\ServerRequestInterface $request) {
    return new React\\Http\\Message\\Response(
        200,
        ['Content-Type' => 'text/plain'],
        "Hello, Async World!"
    );
});
$socket = new React\\Socket\\Server('127.0.0.1:8080', $loop);
$server->listen($socket);
echo "服务器已启动于 http://127.0.0.1:8080";
$loop->run();

Amp

Amp 使用协程(基于生成器的协程)并提供更高级的 API。您使用 yield 和 await 而不是 then() 链,这使得代码看起来像同步代码。

// 使用 Amp 的示例
\\Amp\\Loop::run(function () {
    $response = yield \\Amp\\Http\\Client\\HttpClient::request('http://example.com');
    $body = yield $response->getBody()->buffer();
    echo $body;
});

Fiber:PHP 8.1 核心中的异步特性

从 PHP 8.1 开始,语言中添加了

博客

书籍推荐