Guzzle7[實戰系列]

豎橫山發表於2023-03-07

版本說明

guzzle/guzzle 是 GuzzleHttp 第 3 版的一個較早的版本,它是在 GuzzleHttp 之前最受歡迎的版本之一,但它已經不再維護。
guzzlehttp/guzzle 是 GuzzleHttp 第 6 版的一個分支,它是目前推薦使用的 GuzzleHttp 版本。它也提供了更好的 PSR 支援和更好的非同步請求處理方式

要求

  • PHP >= 7.2.5
  • 如果使用stream,必須開啟allow_url_fopen
  • 如果使用curl,curl擴充套件版本必須>= 7.19.4

安裝

composer require guzzlehttp/guzzle:^7.0

快速啟動

require_once 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
    'base_uri' => 'http://httpbin.org',
    'timeout' => 2.0, //超時時間2秒
]);
// 傳送請求 http://httpbin.org/test
$response = $client->request('GET', 'test');
// 傳送請求 http://httpbin.org/root
$response = $client->request('GET', '/root');
//也可以這樣發起請求
$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');
//可以先例項化Request,再發起請求
use GuzzleHttp\Psr7\Request;
$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);

傳送非同步請求

$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');
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();
    }
)->wait();

併發傳送請求

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')
];
//等待全部請求返回,如果其中一個請求失敗會丟擲異常
$responses = Promise\Utils::unwrap($promises);
//等待全部請求返回,允許某些請求失敗
$responses = Promise\Utils::settle($promises)->wait();

使用Response

$code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK
//header是否存在Content-Length
if ($response->hasHeader('Content-Length')) {
    echo "It exists";
}

//獲取Content-Length的值
echo $response->getHeader('Content-Length')[0];
//全部header
foreach ($response->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values) . "\r\n";
}

//getBody返回的是實現了StreamInterface介面的流物件
$body = $response->getBody();
//StreamInterface實現了__toString()方法,可以直接輸出
echo $body;
//顯示轉換成字串
$stringBody = (string) $body;
//當作流一樣使用,使用read方法讀取
$tenBytes = $body->read(10);
//讀取剩餘內容
$remainingBytes = $body->getContents();

query引數的幾種寫法

//1
$response = $client->request('GET', 'http://httpbin.org?foo=bar');
//2 會自動使用http_build_query 
$client->request('GET', 'http://httpbin.org', [
    'query' => ['foo' => 'bar']
]);
//3
$client->request('GET', 'http://httpbin.org', ['query' => 'foo=bar']);

上傳資料

//$body是字串資料
$r = $client->request('POST', 'http://httpbin.org/post', [
    'body' => 'raw data'
]);

// $body是檔案控制程式碼
$body = Psr7\Utils::tryFopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

// body是PSR-7 stream流.
$body = Psr7\Utils::streamFor('hello!');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

表單上傳

// application/x-www-form-urlencoded
$response = $client->request('POST', 'http://httpbin.org/post', [
    'form_params' => [
        'field_name' => 'abc',
        'other_field' => '123',
        'nested_field' => [
            'nested' => 'hello'
        ]
    ]
]);

//multipart/form-data
use GuzzleHttp\Psr7;

$response = $client->request('POST', 'http://httpbin.org/post', [
    'multipart' => [
        [
            'name'     => 'field_name',//表單name
            'contents' => 'abc'//表單值
        ],
        [
            'name'     => 'file_name',//檔名
            'contents' => Psr7\Utils::tryFopen('/path/to/file', 'r')//檔案控制程式碼
        ],
        [
            'name'     => 'other_file',//沒太看懂,前面兩種夠用了
            'contents' => 'hello',
            'filename' => 'filename.txt',
            'headers'  => [
                'X-Foo' => 'this is an extra header to include'
            ]
        ]
    ]
]);

Cookies

//組裝cookie
$jar = \GuzzleHttp\Cookie\CookieJar::fromArray(
    [
        'some_cookie' => 'foo',
        'other_cookie' => 'barbaz1234'
    ],
    'example.org' //域名
);

//帶cookies發起請求
$jar = new \GuzzleHttp\Cookie\CookieJar;
$r = $client->request('GET', 'http://httpbin.org/cookies', [
    'cookies' => $jar
]);

//client共享cookie
$client = new \GuzzleHttp\Client(['cookies' => true]);
$r = $client->request('GET', 'http://httpbin.org/cookies');

異常樹

. \RuntimeException
└── TransferException (implements GuzzleException)
    ├── ConnectException (implements NetworkExceptionInterface) //網路錯誤
    └── RequestException
        ├── BadResponseException
        │   ├── ServerException //500錯誤
        │   └── ClientException //400錯誤
        └── TooManyRedirectsException //太多重定向

常用的請求

//BASIC 授權
$client->request('GET', '/get', ['auth' => ['username', 'password']]);

//DIGEST授權
$client->request('GET', '/get', [
    'auth' => ['username', 'password', 'digest']
]);

//連線超時時間,0為無限期
$client->request('GET', '/delay/5', ['connect_timeout' => 3.14]);

//設定header
// Set various headers on a request
$client->request('GET', '/get', [
    'headers' => [
        'User-Agent' => 'testing/1.0',
        'Accept'     => 'application/json',
        'X-Foo'      => ['Bar', 'Baz']
    ]
]);

//請求超時
$client->request('GET', '/delay/5', ['timeout' => 3.14]);

總結

再見自己寫的curl函式,擁抱guzzlehttp,還支援非同步請求,推薦指數:五老星

本作品採用《CC 協議》,轉載必須註明作者和本文連結
遇強則強,太強另說

相關文章