[guzzlehttp/guzzle]使用起来更优雅的HTTP客户端

谭昱
2023-12-01

在处理业务时,我们总是会发起一个http请求,比如请求远程接口,或者下载一个文件.很显然,在PHP中需要使用CURL,但是curl写起来实在是太不舒服了,又难写,也不易阅读.实际上PHP有很多扩展可以非常优雅的实现http请求,比如这篇文章要介绍的:guzzlehttp/guzzle.

guzzle的特点:

  • 接口简单:无论是一个简单地get请求,还是设置cookie,上传大文件,写起来都很简单
  • 可以发起异步请求,并且用法与同步请求一致
  • 使用PSR-7接口来请求、响应、分流,允许你使用其他兼容的PSR-7类库与Guzzle共同开发。
  • 抽象底层,并非完全依赖curl,也有其他的实现方式,比如php的stream或者socket
  • 支持中间件模式

一段guzzle的代码如下:

$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.github.com/user', [
    'auth' => ['user', 'pass']
]);
echo $res->getStatusCode();
// "200"
echo $res->getHeader('content-type')[0];
// 'application/json; charset=utf8'
echo $res->getBody();
// {"type":"User"...'

// 发送一个异步请求.
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
$promise = $client->sendAsync($request)->then(function ($response) {
    echo '加载完成! ' . $response->getBody();
});
$promise->wait();

相对于curl的写法,很简单,也很容易理解.

并且guzzle支持并发请求:

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client(['base_uri' => 'http://httpbin.org/']);

// 把要发起的请求组织起来
$promises = [
    'image' => $client->getAsync('/image'),
    'png'   => $client->getAsync('/image/png'),
    'jpeg'  => $client->getAsync('/image/jpeg'),
    'webp'  => $client->getAsync('/image/webp')
];

// 等待所求请求完成.
$results = Promise\unwrap($promises);

// 如果需要处理每一个请求结果
// function.
echo $results['image']->getHeader('Content-Length');
echo $results['png']->getHeader('Content-Length');

也支持发起异步的一定数量的请求:

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;

$client = new Client();

$requests = function ($total) {
    $uri = 'http://127.0.0.1:8126/guzzle-server/perf';
    for ($i = 0; $i < $total; $i++) {
        yield new Request('GET', $uri);
    }
};

$pool = new Pool($client, $requests(100), [
    'concurrency' => 5,
    'fulfilled' => function (Response $response, $index) {
        // 当请求成功后
    },
    'rejected' => function (RequestException $reason, $index) {
        // 当请求失败后 
    },
]);

// 等待请求完成
$promise = $pool->promise();

// 强制结束请求
$promise->wait();

使用guzzle实现简单又易读的代码.

 类似资料: