当前位置:首页 > PHP教程 > php高级应用 > 列表

浅析PHP如何并行异步处理HTTP请求

发布:smiling 来源: PHP粉丝网  添加日期:2026-02-03 20:36:55 浏览: 评论:0 

在 PHP 中,由于其传统的同步阻塞模型,实现并行异步处理 HTTP 请求并不像其他语言(如 Go 或 Node.js)那样直接。不过,仍然可以通过一些扩展和工具来实现并行异步处理。以下是几种常见的方法:

1. 使用 cURL 的多线程功能

PHP 的 cURL 扩展支持多线程处理,可以通过 curl_multi_* 系列函数实现并行 HTTP 请求。

示例代码:

  1. $urls= [ 
  2.  
  3. 'https://example.com/api/1'
  4.  
  5. 'https://example.com/api/2'
  6.  
  7. 'https://example.com/api/3'
  8.  
  9. ]; 
  10.  
  11. $mh= curl_multi_init(); // 初始化多线程 cURL 
  12.  
  13. $handles= []; 
  14.  
  15. foreach($urlsas$url) { 
  16.  
  17. $ch= curl_init(); 
  18.  
  19. curl_setopt($ch, CURLOPT_URL, $url); 
  20.  
  21. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
  22.  
  23. curl_multi_add_handle($mh$ch); // 将单个 cURL 句柄添加到多线程中 
  24.  
  25. $handles[] = $ch
  26.  
  27.  
  28. $running= null; 
  29.  
  30. do
  31.  
  32. curl_multi_exec($mh$running); // 执行并行请求 
  33.  
  34. curl_multi_select($mh); // 等待活动 
  35.  
  36. while($running> 0); 
  37.  
  38. $responses= []; 
  39.  
  40. foreach($handlesas$ch) { 
  41.  
  42. $responses[] = curl_multi_getcontent($ch); // 获取每个请求的响应 
  43.  
  44. curl_multi_remove_handle($mh$ch); // 移除句柄 
  45.  
  46. curl_close($ch); 
  47.  
  48.  
  49. curl_multi_close($mh); // 关闭多线程 cURL 
  50.  
  51. print_r($responses); 

优点:

原生支持,无需额外扩展。

可以并行处理多个 HTTP 请求。

缺点:

代码复杂度较高。

需要手动管理句柄和状态。

2. 使用 Guzzle 异步客户端

Guzzle 是一个流行的 PHP HTTP 客户端库,支持异步请求。

示例代码:

  1. require'vendor/autoload.php'
  2.  
  3. useGuzzleHttp\Client; 
  4.  
  5. useGuzzleHttp\Promise; 
  6.  
  7. $client= newClient(); 
  8.  
  9. $urls= [ 
  10.  
  11. 'https://example.com/api/1'
  12.  
  13. 'https://example.com/api/2'
  14.  
  15. 'https://example.com/api/3'
  16.  
  17. ]; 
  18.  
  19. $promises= []; 
  20.  
  21. foreach($urlsas$url) { 
  22.  
  23. $promises[] = $client->getAsync($url); // 发起异步请求 
  24.  
  25.  
  26. $responses= Promise\Utils::settle($promises)->wait(); // 等待所有请求完成 
  27.  
  28. foreach($responsesas$response) { 
  29.  
  30. if($response['state'] === 'fulfilled') { 
  31.  
  32. echo$response['value']->getBody() . "\n"// 输出响应内容 
  33.  
  34. else
  35.  
  36. echo'Request failed: '$response['reason']->getMessage() . "\n"
  37.  
  38.  

优点:

代码简洁,易于使用。

支持并发请求和异步处理。

缺点:

需要安装 Guzzle 库。

3. 使用 Swoole 扩展

Swoole 是一个高性能的 PHP 扩展,支持异步、协程和并行处理。

示例代码:

  1. Swoole\Runtime::enableCoroutine(); // 启用协程 
  2.  
  3. $urls= [ 
  4.  
  5. 'https://example.com/api/1'
  6.  
  7. 'https://example.com/api/2'
  8.  
  9. 'https://example.com/api/3'
  10.  
  11. ]; 
  12.  
  13. $responses= []; 
  14.  
  15. go(function() use($urls, &$responses) { 
  16.  
  17. $client= newSwoole\Coroutine\Http\Client('example.com', 443, true); 
  18.  
  19. foreach($urlsas$url) { 
  20.  
  21. $client->get($url); 
  22.  
  23. $responses[] = $client->body; 
  24.  
  25.  
  26. }); 
  27.  
  28. Swoole\Event::wait(); // 等待所有协程完成 
  29.  
  30. print_r($responses); 

优点:

高性能,支持协程和异步 I/O。

适合高并发场景。

缺点:

需要安装 Swoole 扩展。

学习曲线较高。

4. 使用 ReactPHP

ReactPHP 是一个基于事件驱动的 PHP 库,支持异步编程。

示例代码:

  1. require'vendor/autoload.php'
  2.  
  3. useReact\EventLoop\Factory; 
  4.  
  5. useReact\HttpClient\Client; 
  6.  
  7. useReact\HttpClient\Response; 
  8.  
  9. $loop= Factory::create(); 
  10.  
  11. $client= newClient($loop); 
  12.  
  13. $urls= [ 
  14.  
  15. 'https://example.com/api/1'
  16.  
  17. 'https://example.com/api/2'
  18.  
  19. 'https://example.com/api/3'
  20.  
  21. ]; 
  22.  
  23. foreach($urlsas$url) { 
  24.  
  25. $request$client->request('GET'$url); 
  26.  
  27. $request->on('response'function(Response $response) { 
  28.  
  29. $response->on('data'function($chunk) { 
  30.  
  31. echo$chunk
  32.  
  33. }); 
  34.  
  35. }); 
  36.  
  37. $request->end(); 
  38.  
  39.  
  40. $loop->run(); 

优点:

基于事件驱动,适合异步编程。

支持长连接和流式处理。

缺点:

需要安装 ReactPHP 库。

代码复杂度较高。

5. 使用多进程(pcntl 扩展)

PHP 的 pcntl 扩展支持多进程编程,可以通过创建子进程来实现并行处理。

示例代码:

  1. $urls= [ 
  2.  
  3. 'https://example.com/api/1'
  4.  
  5. 'https://example.com/api/2'
  6.  
  7. 'https://example.com/api/3'
  8.  
  9. ]; 
  10.  
  11. $children= []; 
  12.  
  13. foreach($urlsas$url) { 
  14.  
  15. $pid= pcntl_fork(); 
  16.  
  17. if($pid== -1) { 
  18.  
  19. die('Could not fork'); 
  20.  
  21. elseif($pid) { 
  22.  
  23. $children[] = $pid// 父进程记录子进程 ID 
  24.  
  25. else
  26.  
  27. // 子进程处理请求 
  28.  
  29. echofile_get_contents($url) . "\n"
  30.  
  31. exit(); // 子进程退出 
  32.  
  33.  
  34.  
  35. // 父进程等待所有子进程完成 
  36.  
  37. foreach($childrenas$pid) { 
  38.  
  39. pcntl_waitpid($pid$status); 
  40.  

优点:

真正的并行处理。

适合 CPU 密集型任务。

缺点:

需要 pcntl 扩展。

进程间通信复杂。

总结

cURL 多线程:适合简单的并行 HTTP 请求。

Guzzle:代码简洁,适合大多数场景。

Swoole:高性能,适合高并发场景。

ReactPHP:基于事件驱动,适合异步编程。

多进程:适合 CPU 密集型任务,但复杂度较高。

根据具体需求选择合适的方法即可。

Tags: PHP并行异步处理 PHP异步处理HTTP请求

分享到: