guzzle包使用


guzzle包使用


正文

你可能习惯了在项目中自己封装Curl族函数实现请求,可以尝试使用下封装好的 guzzlehttp/guzzle 包。

Guzzle 是一个 PHP HTTP 客户端,可以轻松发送 HTTP 请求并轻松与 Web 服务集成。

用于构建查询字符串、POST 请求、流式传输大型上传、流式传输大型下载、使用 HTTP cookie、上传 JSON 数据等的简单界面…

可以使用相同的接口发送同步和异步请求。

对请求、响应和流使用 PSR-7 接口。 这允许您在 Guzzle 中使用其他 PSR-7 兼容库。

支持 PSR-18 允许其他 PSR-18 HTTP 客户端之间的互操作性。

抽象出底层 HTTP 传输,允许您编写与环境和传输无关的代码; 即,对 cURL、PHP 流、sockets或非阻塞事件循环没有硬依赖。

中间件系统允许您增强和组合客户端行为。

安装

guzzlehttp/guzzle包现在的版本到了 7.4.x 版,项目安装 guzzlehttp/guzzle,指定版本,不然安装的是dev版:

composer require guzzlehttp/guzzle 7.4.1

root@02891538d8c9:/var/www/html/test# composer require guzzlehttp/guzzle 7.4.1
The "fxp/composer-asset-plugin" plugin (installed globally) was skipped because it requires a Plugin API version ("^1.0") that does not match your Composer installation ("2.3.0"). You may need to run composer update with the "--no-plugins" option.
./composer.json has been updated
The "fxp/composer-asset-plugin" plugin (installed globally) was skipped because it requires a Plugin API version ("^1.0") that does not match your Composer installation ("2.3.0"). You may need to run composer update with the "--no-plugins" option.
Running composer update guzzlehttp/guzzle
Loading composer repositories with package information
Updating dependencies
Lock file operations: 8 installs, 0 updates, 0 removals
  - Locking guzzlehttp/guzzle (7.4.1)
  - Locking guzzlehttp/promises (dev-master fe752ae)
  - Locking guzzlehttp/psr7 (dev-master f8ae7cb)
  - Locking psr/http-client (dev-master 22b2ef5)
  - Locking psr/http-factory (dev-master 36fa03d)
  - Locking psr/http-message (dev-master efd67d1)
  - Locking ralouphie/getallheaders (3.0.3)
  - Locking symfony/deprecation-contracts (2.5.x-dev e8b495e)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 8 installs, 0 updates, 0 removals
  - Installing symfony/deprecation-contracts (2.5.x-dev e8b495e): Extracting archive
  - Installing psr/http-message (dev-master efd67d1): Extracting archive
  - Installing psr/http-client (dev-master 22b2ef5): Extracting archive
  - Installing ralouphie/getallheaders (3.0.3): Extracting archive
  - Installing psr/http-factory (dev-master 36fa03d): Extracting archive
  - Installing guzzlehttp/psr7 (dev-master f8ae7cb): Extracting archive
  - Installing guzzlehttp/promises (dev-master fe752ae): Extracting archive
  - Installing guzzlehttp/guzzle (7.4.1): Extracting archive
3 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
4 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
root@02891538d8c9:/var/www/html/test#

创建客户端

$client = new Client([
    // Base URI is used with relative requests
    'base_uri' => 'http://httpbin.org',
    // You can set any number of default request options.
    'timeout'  => 2.0,
]);

同步请求

$response = $client->request('GET', 'ip');  // http://httpbin.org/ip
$response = $client->get('http://httpbin.org/get');
$response = $client->delete('http://httpbin.org/delete');
$response = $client->head('http://httpbin.org/get');
$response = $client->options('http://httpbin.org/get');
$response = $client->patch('http://httpbin.org/patch');
$response = $client->post('http://httpbin.org/post');
$response = $client->put('http://httpbin.org/put');

创建一个请求:

use GuzzleHttp\Psr7\Request;

$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');

echo $response->getStatusCode(); // 200
echo $response->getReasonPhrase(); // OK
print_r($response->getHeader('content-type'));  // Array( [0] => application/json; charset=utf-8 )
echo $response->getHeaderLine('content-type'); // 'application/json; charset=utf8'
echo $response->getBody(); // '{"id": 1420053, "name": "guzzle", ...}'

异步请求

$promise = $client->getAsync('http://httpbin.org/get');
$promise = $client->deleteAsync('http://httpbin.org/delete');
$promise = $client->headAsync('http://httpbin.org/get');
$promise = $client->optionsAsync('http://httpbin.org/get');
$promise = $client->patchAsync('http://httpbin.org/patch');
$promise = $client->postAsync('http://httpbin.org/post');
$promise = $client->putAsync('http://httpbin.org/put');

创建一个请求:

// Send an asynchronous request.
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
$promise = $client->sendAsync($request)->then(function ($response) {
    echo 'I completed! ' . $response->getBody();
});

$promise->wait();
$headers = ['X-Foo' => 'Bar'];
$body = 'Hello!';
$request = new Request('HEAD', 'http://httpbin.org/head', $headers, $body);
$promise = $client->sendAsync($request);

// Or, if you don't need to pass in a request instance:
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(
    function (ResponseInterface $res) {
        echo $res->getStatusCode() . "\n";
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
);

并发请求

使用 Promise 和异步请求同时发送多个请求:

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

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

// Initiate each request but do not block
$promises = [
    'image' => $client->getAsync('/image'),
    'png'   => $client->getAsync('/image/png'),
    'jpeg'  => $client->getAsync('/image/jpeg'),
    'webp'  => $client->getAsync('/image/webp')
];

// Wait for the requests to complete; throws a ConnectException
// if any of the requests fail
$responses = Promise\Utils::unwrap($promises);

// You can access each response using the key of the promise
echo $responses['image']->getHeader('Content-Length')[0];
echo $responses['png']->getHeader('Content-Length')[0];

// Wait for the requests to complete, even if some of them fail
$responses = Promise\Utils::settle($promises)->wait();

// Values returned above are wrapped in an array with 2 keys: "state" (either fulfilled or rejected) and "value" (contains the response)
echo $responses['image']['state']; // returns "fulfilled"
echo $responses['image']['value']->getHeader('Content-Length')[0];
echo $responses['png']['value']->getHeader('Content-Length')[0];

发送的请求数量不确定时,您可以使用 GuzzleHttp\Pool 对象:

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) {
        // this is delivered each successful response
    },
    'rejected' => function (RequestException $reason, $index) {
        // this is delivered each failed request
    },
]);

// Initiate the transfers and create a promise
$promise = $pool->promise();

// Force the pool of requests to complete.
$promise->wait();

或者使用闭包:

$client = new Client();

$requests = function ($total) use ($client) {
    $uri = 'http://127.0.0.1:8126/guzzle-server/perf';
    for ($i = 0; $i < $total; $i++) {
        yield function() use ($client, $uri) {
            return $client->getAsync($uri);
        };
    }
};

$pool = new Pool($client, $requests(100));

使用响应

code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK

// Check if a header exists.
if ($response->hasHeader('Content-Length')) {
    echo "It exists";
}

// Get a header from the response.
echo $response->getHeader('Content-Length')[0];

// Get all of the response headers.
foreach ($response->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values) . "\r\n";
}

$body = $response->getBody();
// Implicitly cast the body to a string and echo it
echo $body;
// Explicitly cast the body to a string
$stringBody = (string) $body;
// Read 10 bytes from the body
$tenBytes = $body->read(10);
// Read the remaining contents of the body as a string
$remainingBytes = $body->getContents();

httpbin

httpbin 是一个简单的 HTTP 请求和响应服务。

网址:http://httpbin.org

提供了各种服务请求地址。

参考资料

guzzle/guzzle https://github.com/guzzle/guzzle

guzzlehttp/guzzle https://packagist.org/packages/guzzlehttp/guzzle

Guzzle Documentation https://docs.guzzlephp.org/en/stable/

PSR-7 HTTP 消息接口规范 https://learnku.com/docs/psr/psr-7-http-message/1616

httpbin http://www.httpbin.org/


返回