GuzzleHttp 使用筆記(基於 cURL 的 HTTP 請求套件)

📌 功能介紹

GuzzleHttp 是一個功能完整的 PHP HTTP 客戶端,基於 cURL 封裝,讓開發者可以更方便地與 Web API 通訊。具備以下特性:

  • 簡潔直觀的 API:透過簡單語法發送 GET、POST、PUT、DELETE 等請求。
  • 支援非同步請求:透過 Promise 進行異步操作。
  • 支援中介層(Middleware):可在請求前後添加自定邏輯(如驗證、記錄、重試等)。
  • 相容 PSR-7 / PSR-18 標準:可與其他遵循標準的框架/函式庫整合。
  • 支援檔案上傳與下載:提供簡便介面處理 multipart 請求。

📌 GuzzleHttp 與原生 cURL 比較

項目 GuzzleHttp cURL (PHP 原生)
抽象層級 高層封裝,簡潔易懂 低層操作,需設定多項選項
語法簡潔性 使用鏈式呼叫與關聯陣列設定 需多行程式碼設定選項與處理回應
擴充性/標準支援 支援 PSR-7/18 標準,具高可替換性 無標準支援,與框架整合不易
非同步支援 支援 Promise 非同步請求 無原生非同步支援
中介層機制 可設置中間件 無內建支援
文件處理 內建支援 multipart、下載流處理 需自行處理 fopen、stream 等細節

📦 安裝

composer require guzzlehttp/guzzle

📥 使用方式

基本使用(POST 表單傳值)

use GuzzleHttp\Client;

$client = new Client();

$response = $client->post('https://example.com/api', [
    'form_params' => [
        'key1' => 'value1',
        'key2' => 'value2',
    ]
]);

echo $response->getBody();

傳送 JSON 請求(含 Header 設定)

$response = $client->post('https://example.com/api', [
    'headers' => [
        'Authorization' => 'Bearer your-token',
        'Content-Type' => 'application/json',
    ],
    'json' => [
        'key' => 'value'
    ]
]);

echo $response->getBody();

發送 GET 請求

$response = $client->get('https://jsonplaceholder.typicode.com/posts/1');

echo $response->getBody();

回應處理:解析 JSON

$data = json_decode($response->getBody(), true);

echo $data['id'];

回應處理:使用 getContents()

$contents = $response->getBody()->getContents();

🚨 錯誤處理與例外

GuzzleHttp 提供多種例外類別可供辨識錯誤類型:

  • RequestException:所有 HTTP 請求相關錯誤的基底類別。
  • ClientException:對應 HTTP 4xx 錯誤(客戶端錯)。
  • ServerException:對應 HTTP 5xx 錯誤(伺服器端錯)。
  • ConnectException:網路連線失敗(如 DNS 錯誤、超時)。
  • TooManyRedirectsException:超過重定向限制。

範例:完整 try-catch 錯誤處理

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\TooManyRedirectsException;

$client = new Client();

try {
    $response = $client->request('GET', 'https://example.com/api');
    echo $response->getBody();
} catch (ClientException $e) {
    echo "Client error: " . $e->getMessage();
} catch (ServerException $e) {
    echo "Server error: " . $e->getMessage();
} catch (ConnectException $e) {
    echo "Connection error: " . $e->getMessage();
} catch (TooManyRedirectsException $e) {
    echo "Too many redirects: " . $e->getMessage();
} catch (RequestException $e) {
    if ($e->hasResponse()) {
        $statusCode = $e->getResponse()->getStatusCode();
        $reason = $e->getResponse()->getReasonPhrase();
        echo "Request failed with status code $statusCode: $reason";
    } else {
        echo "Request failed: " . $e->getMessage();
    }
} catch (\Exception $e) {
    echo "Other error: " . $e->getMessage();
}

📚 相關連結