你有没有遇到过这样的情况:你的PHP应用需要同时从多个外部API获取数据,比如获取用户订单详情、商品库存信息、物流状态等等。传统的做法,你可能会这样写代码:
<pre class="brush:php;toolbar:false;">// 伪代码,实际会使用curl或Guzzle HTTP客户端
$orderData = fetchApi('order_api/get_details'); // 耗时操作1
$stockData = fetchApi('stock_api/get_info'); // 耗时操作2
$shippingData = fetchApi('shipping_api/get_status'); // 耗时操作3
// 处理所有数据...这段代码看似简单,但问题在于,
fetchapi
传统上,为了解决这个问题,开发者们可能会尝试使用
curl_multi
幸好,PHP生态系统日益成熟,Composer的普及让引入和管理外部库变得前所未有的简单。而今天的主角,正是
guzzlehttp/promises
Composer在线学习地址:学习地址
guzzlehttp/promises
立即学习“PHP免费学习笔记(深入)”;
这个库的核心优势在于它能够以迭代的方式处理Promise的链式调用和解析,这意味着你可以进行“无限”的Promise链式操作,而不会导致栈溢出,这对于复杂的异步流程管理至关重要。
它如何解决我们的阻塞问题?
guzzlehttp/promises
guzzlehttp/promises
使用Composer安装
guzzlehttp/promises
<pre class="brush:php;toolbar:false;">composer require guzzlehttp/promises
Composer 会自动下载并安装该库及其所有依赖项,并生成
vendor/autoload.php
<pre class="brush:php;toolbar:false;"><?php require 'vendor/autoload.php'; // 你的代码...
让我们来看一个使用
guzzlehttp/promises
guzzlehttp/promises
<pre class="brush:php;toolbar:false;"><?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\Utils; // 2.x 版本使用 Utils
// 假设我们有三个模拟的API端点,它们会模拟延迟
$apiEndpoints = [
'https://jsonplaceholder.typicode.com/posts/1', // 模拟请求1
'https://jsonplaceholder.typicode.com/todos/1', // 模拟请求2
'https://jsonplaceholder.typicode.com/users/1' // 模拟请求3
];
$client = new Client();
$promises = [];
echo "开始并发请求...\n";
$startTime = microtime(true);
foreach ($apiEndpoints as $index => $url) {
// client->getAsync() 会立即返回一个Promise对象,不会阻塞
$promises['request_' . ($index + 1)] = $client->getAsync($url);
}
// 使用 Utils::all() 等待所有Promise完成
// Utils::all() 会返回一个新的Promise,当所有内部Promise都 fulfilled 时,它才 fulfilled
// 如果任何一个内部Promise rejected,它就会 rejected
$allPromises = Utils::all($promises);
try {
// wait() 方法会阻塞当前脚本,直到Promise被解析(fulfilled或rejected)
// 这里的 wait() 会等待所有的并发请求都完成后才继续执行
$results = $allPromises->wait();
echo "所有请求完成!\n";
foreach ($results as $key => $response) {
echo "{$key} 响应状态码: " . $response->getStatusCode() . "\n";
// 你可以进一步处理 $response->getBody()->getContents()
}
} catch (GuzzleHttp\Promise\Exception\RejectionException $e) {
echo "请求中发生错误: " . $e->getReason() . "\n";
}
$endTime = microtime(true);
echo "总耗时: " . round($endTime - $startTime, 3) . " 秒\n";
// 对比:如果串行执行,总耗时会是单个请求耗时之和。
// 使用 Promise 后的总耗时会接近最慢的那个请求的耗时。在这个例子中:
getAsync()
getAsync()
Utils::all($promises)
$allPromises->wait()
curl_multi
then()
otherwise()
otherwise()
try-catch
guzzlehttp/promises
如果你还在为PHP的阻塞问题而烦恼,那么现在就是时候拥抱Composer和
guzzlehttp/promises
以上就是如何解决PHP异步操作的阻塞问题?使用Composer与GuzzlePromises轻松实现并发!的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号