
当大多数开发者想到 PHP 时,首先想到的就是它的 同步、请求–响应模型:PHP 脚本从上到下、逐行运行,阻塞直到每个操作完成。多年来,这足以满足网页和小应用程序的需求。
但是现代应用程序通常需要处理 并发任务:长时间运行的数据库查询、流式数据、对第三方 API 的 HTTP 请求,或处理数千个 WebSocket 连接。引入 事件循环 — PHP 中异步 I/O 的动力机制。
在其核心上,事件循环就像一个 交通控制器。它不是强迫你的程序等待每个操作完成,而是注册“任务”(如文件读取、网络请求、定时器等 I/O 操作),并持续检查哪些任务准备好继续。
以下是它的工作原理的简单说明:
启动循环。
注册任务(例如读取文件或查询 API)。
循环运行,检查已完成的任务。
当任务准备好时,执行相应的回调。
循环继续运行,直到没有更多任务为止。
有趣的事实:Facebook 的 HHVM 曾经直接在 PHP 中实验 async/await,但主流 PHP 尚未原生采用它。像 Amp 这样的库使用生成器有效地“polyfill”了这种行为。
传统上,PHP 没有像 Node.js 那样的内置事件循环。然而,库 如 ReactPHP 和 Amp 为该语言带来了这种能力。它们在纯 PHP 中实现事件循环,并允许开发者编写异步代码,而无需更改底层 PHP 运行时。
以下是使用 ReactPHP 的事件循环创建一个简单定时器的最小示例:
<?phprequire 'vendor/autoload.php';use React\EventLoop\Factory;$loop = Factory::create();// Add a timer that runs once after 2 seconds$loop->addTimer(2, function () {echo "2 seconds have passed!\n";});// Add a periodic timer every second$loop->addPeriodicTimer(1, function () {echo "Tick: " . time() . "\n";});// Run the loop$loop->run();
这里发生了什么?
循环在后台持续运行。
每秒打印当前时间戳。
2 秒后,运行一次性回调。
这是 非阻塞 的:循环等待时,PHP 可以并发处理其他 I/O 操作。
ReactPHP 与 Amp:ReactPHP 专注于基于回调的编程,而 Amp 使用 协程和类似 async/await 的语法,使代码看起来更同步且易读。 PHP 中的 WebSockets:感谢事件循环,你可以用 PHP 编写实时聊天应用程序 — 以前这几乎不可能,除非依赖外部服务。 PHP 中的流式传输:无需等待大型文件完全下载,你可以使用异步 I/O 逐块流式传输它。 性能:虽然对于某些工作负载不如 Node.js 或 Go 快,但异步 PHP 可以处理数千个并发连接 — 传统 PHP 永远无法实现这一点。
API 驱动的应用程序:如果你的应用集成多个 API,异步 PHP 允许你并行发出请求,而不是顺序执行。 实时应用:聊天服务器、实时仪表板、多人游戏 — 借助事件循环,这些在 PHP 中都成为可能。 微服务:事件驱动架构与异步 I/O 自然搭配。

ReactPHP 与 Amp:并排示例
假设我们想 并行获取两个 API 端点。传统上,PHP 会顺序获取它们,阻塞直到第一个完成才开始第二个。使用事件循环,可以同时发出两个请求。
<?phprequire 'vendor/autoload.php';use React\EventLoop\Factory;use React\Http\Browser;$promises = [$browser->get('https://jsonplaceholder.typicode.com/posts/1'),$browser->get('https://jsonplaceholder.typicode.com/posts/2'),];foreach ($promises as $promise) {$promise->then(function (Psr\Http\Message\ResponseInterface $response) {echo "Response: " . substr((string) $response->getBody(), 0, 50) . "...\n";},function (Exception$e) {echo "Error: " . $e->getMessage() . "\n";});}$loop->run();
关键要点:
你使用 promise 和回调。
语法感觉更“底层”,但你获得精确控制。
<?phprequire 'vendor/autoload.php';use Amp\Http\Client\HttpClientBuilder;use Amp\Http\Client\Request;use function Amp\async;Amp\Loop::run(function () {$client = HttpClientBuilder::buildDefault();$tasks = [async(fn () => $client->request(new Request('https://jsonplaceholder.typicode.com/posts/1'))),async(fn () => $client->request(new Request('https://jsonplaceholder.typicode.com/posts/2'))),];foreach ($tasks as $task) {$response = yield $task;$body = yield $response->getBody()->buffer();echo "Response: " . substr($body, 0, 50) . "...\n";}});
关键要点:
感谢 yield 和协程,代码看起来几乎 同步。
对于来自同步 PHP 的开发者来说,更易读和维护。
*ReactPHP:如果你熟悉回调并想要轻量级的底层工具,那就很棒。 *Amp:如果你想要类似 async/await 的语法,感觉更接近现代 JavaScript 或 Python 的异步编程,那就更好。
两者都是 经过实战检验 的,并在生产环境中广泛使用。
PHP 可能起源于同步脚本语言,但随着 ReactPHP 和 Amp 等库引入事件循环,它正在演变为能够处理 现代、并发、事件驱动应用程序 的工具。
下次你构建实时应用或需要优化 API 调用时,考虑使用事件循环。PHP 不再只是请求-响应 — 它现在可以运行 异步、长寿命进程,跟上当今苛求的应用程序。
👉 专业提示:如果你想实验,从 ReactPHP 的事件循环开始,然后探索 Amp 的基于协程的语法。你会发现 PHP 的全新一面,你从未想过它存在。