首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 發送 POST 請求的三種方式:stream_context、cURL、Guzzle 對比

     編輯:PHP 相關知識

方式一:原生 stream_context(零依賴)

function postStream(string $url, array $data, array $headers = []): string {
    $opts = [
        'http' => [
            'method'  => 'POST',
            'header'  => array_merge(
                ['Content-Type: application/x-www-form-urlencoded'],
                $headers
            ),
            'content' => http_build_query($data),
            'timeout' => 10,
            'ignore_errors' => true, // 獲取 4xx/5xx 響應體
        ],
        'ssl' => [
            'verify_peer'      => true,
            'verify_peer_name' => true,
        ],
    ];
    $ctx = stream_context_create($opts);
    $response = @file_get_contents($url, false, $ctx);
    if ($response === false) {
        throw new RuntimeException("請求失敗: {$url}");
    }
    return $response;
}

// 使用
$resp = postStream('https://api.example.com/notify', ['event' => 'order_paid', 'order_id' => 12345]);
echo $resp;

優點:無擴展依賴、代碼簡潔。缺點:無自動重試、無連接池、處理複雜場景(多部分表單、流式上傳)困難。

方式二:cURL 擴展(功能最全)

function postCurl(string $url, array $data, array $options = []): string {
    $ch = curl_init($url);
    $defaultOpts = [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_HTTPHEADER     => ['Content-Type: application/x-www-form-urlencoded'],
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS      => 3,
    ];
    curl_setopt_array($ch, array_merge($defaultOpts, $options));
    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($errno) {
        throw new RuntimeException("cURL 錯誤 [{$errno}]: {$error}");
    }
    if ($httpCode >= 400) {
        throw new RuntimeException("HTTP {$httpCode}: {$response}");
    }
    return $response;
}

優點:支援所有 HTTP 特性、性能高、成熟穩定。缺點:API 繁瑣、手動管理資源、錯誤處理分散。

方式三:Guzzle HTTP Client(現代首選)

// composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$client = new Client([
    'base_uri' => 'https://api.example.com/',
    'timeout'  => 10,
    'headers'  => ['User-Agent' => 'MyApp/1.0'],
]);

try {
    $response = $client->post('notify', [
        'form_params' => ['event' => 'order_paid', 'order_id' => 12345],
        // 'json' => [...] 自動設置 Content-Type: application/json
        // 'multipart' => [...] 文件上傳
    ]);
    $body = $response->getBody()->getContents();
    echo $body;
} catch (RequestException $e) {
    if ($e->hasResponse()) {
        echo "HTTP {$e->getResponse()->getStatusCode()}: " . $e->getResponse()->getBody();
    } else {
        echo "網絡異常: {$e->getMessage()}";
    }
}

優點:PSR-7/18 標準、中間件、異步請求、重試策略、測試雙工、文檔豐富。缺點:引入依賴、輕量項目可能過重。

選型建議

場景推薦理由
簡單通知、Webhook、無 Composer 環境stream_context零依賴、內置函數
需精細控制(代理、證書、多部分表單)、舊項目cURL功能完整、無額外依賴
新項目、微服務調用、需重試/熔斷/測試、長期維護Guzzle現代標準、生態豐富、可維護性最強
高併發異步請求Guzzle + Promise / Swoole / Workerman事件驅動、非阻塞

通用最佳實踐

  • ✅ 設置合理超時(連接 3-5s,讀取 10-30s)。
  • ✅ 啟用 SSL 驗證(生產環境絕不關閉)。
  • ✅ 記錄請求/響應日誌(脫敏敏感字段)。
  • ✅ 實現冪等性(幂等 Key)防重複提交。
  • ✅ 熔斷器模式防雪崩(如 Guzzle + CircuitBreaker 中間件)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved