萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 發起 HTTP 請求的三種核心方法詳解

場景

後端服務間調用、抓取遠程頁面、調用第三方 API,PHP 提供了三種原生方式發起 HTTP 請求。

方法一:file_get_contents()(最簡單)

$url = 'https://www.example.com';
$response = file_get_contents($url);
echo $response;

前提: php.ini 中 allow_url_fopen = On。
缺點: 無法自定義 Header、超時、POST 數據、Cookie、處理重定向等,不適合生產環境複雜交互。

方法二:cURL 擴展(功能最全、性能最好,生產首選)

$url = 'https://www.example.com/api';
$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL            => $url,
    CURLOPT_RETURNTRANSFER => true,      // 返回字符串而非直接輸出
    CURLOPT_HEADER         => false,     // 不包含響應頭
    CURLOPT_TIMEOUT        => 10,        // 總超時秒數
    CURLOPT_CONNECTTIMEOUT => 5,         // 連接超時
    CURLOPT_FOLLOWLOCATION => true,      // 自動跟隨 3xx 重定向
    CURLOPT_MAXREDIRS      => 5,         // 最大重定向次數
    CURLOPT_USERAGENT      => 'MyApp/1.0 (PHP/cURL)', // 標識客戶端
    CURLOPT_SSL_VERIFYPEER => true,      // 生產環境務必驗證 SSL 證書
    CURLOPT_SSL_VERIFYHOST => 2,
]);

$response = curl_exec($ch);
if ($response === false) {
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    // 記錄錯誤、拋出異常、降級處理...
}
curl_close($ch);

// 處理響應
$data = json_decode($response, true);

常見進階選項

方法三:fopen() + fgets() 流式讀取(適合大文件/流式處理)

$url = 'https://www.example.com/large-file.log';
$fp = fopen($url, 'r');
if ($fp) {
    while (($line = fgets($fp, 8192)) !== false) {
        // 逐行處理,內存佔用恆定
        processLine(trim($line));
    }
    fclose($fp);
} else {
    // 處理打開失敗
}

注意: 同樣需 allow_url_fopen = On;無法發送 POST、自定義 Header,錯誤處理較繁瑣。

常見坑與排查

  1. 能 ping 通但請求失敗(403/連接重置):目標站開啟了 WAF/防火牆,檢查 User-Agent、Referer、IP 白名單;嘗試用 wget/curl 命令行複現。
  2. HTTPS 證書驗證失敗:CURLOPT_SSL_VERIFYPEER => false 僅用於測試,**生產嚴禁**;正確做法是部署 CA 證書束(cacert.pem)並設置 CURLOPT_CAINFO。
  3. 超時設置無效:確認同時設置了 CURLOPT_CONNECTTIMEOUT(連接階段)和 CURLOPT_TIMEOUT(整個請求)。

現代替代方案:Guzzle / Http\Client (PSR-18)

新項目強烈建議使用 Guzzle 7+ 或實現 Psr\Http\Client\ClientInterface 的客戶端:

use GuzzleHttp\Client;
$client = new Client(['timeout' => 10]);
$response = $client->get('https://api.example.com/users', [
    'headers' => ['Accept' => 'application/json'],
    'query'   => ['page' => 1],
]);
$data = json_decode($response->getBody()->getContents(), true);

優勢:介面統一、中間件支持(重試、日誌、緩存)、異步請求、測試雙、PSR-7/17/18 標準互操作。

copyright © 萬盛學電腦網 all rights reserved
選項用途
CURLOPT_POST啟用 POST 請求
CURLOPT_POSTFIELDSPOST 數據(陣列自動編碼為 multipart/form-data;字符串發送 application/x-www-form-urlencoded)
CURLOPT_HTTPHEADER自定義請求頭(如 ['Content-Type: application/json', 'Authorization: Bearer xxx'])
CURLOPT_COOKIE / CURLOPT_COOKIEJAR/FILE發送/持久化 Cookie
CURLOPT_PROXY代理服務器
CURLOPT_WRITEFUNCTION流式處理大響應體(回調函數)