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

PHP cURL 實作 HTTP GET/POST 請求完整指南

     編輯:PHP 綜合知識

前言

cURL 是 PHP 與外部 HTTP 服務溝通的標準工具,支援完整的協定細節控制。本文提供 GET/POST 請求的標準範本、常用選項解析、錯誤處理與最佳實務。

cURL 基本流程

  1. curl_init() 初始化會話
  2. curl_setopt() 設定選項
  3. curl_exec() 執行請求
  4. curl_close() 關閉會話釋放資源

GET 請求範本

<?php
function httpGet(string $url, array $options = []): ?string
{
    $ch = curl_init();
    $defaultOptions = [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,      // 回傳字串而非直接輸出
        CURLOPT_HEADER         => false,     // 不包含回應標頭
        CURLOPT_FOLLOWLOCATION => true,      // 跟隨重導向
        CURLOPT_MAXREDIRS      => 5,         // 最大重導向次數
        CURLOPT_TIMEOUT        => 10,        // 總超時秒數
        CURLOPT_CONNECTTIMEOUT => 5,         // 連線超時秒數
        CURLOPT_SSL_VERIFYPEER => true,      // 驗證 SSL 憑證
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_USERAGENT      => 'MyApp/1.0 (+https://example.com/bot)',
    ];
    curl_setopt_array($ch, array_merge($defaultOptions, $options));
    $response = curl_exec($ch);
    if ($response === false) {
        error_log('cURL GET error: ' . curl_error($ch) . ' (Code: ' . curl_errno($ch) . ')');
    }
    curl_close($ch);
    return $response;
}

// 使用
$html = httpGet('https://api.example.com/users?page=1&limit=20');
$data = $html ? json_decode($html, true) : null;

POST 請求範本

<?php
function httpPost(string $url, array $data, array $options = []): ?string
{
    $ch = curl_init();
    $postFields = is_array($data) ? http_build_query($data) : $data;
    $defaultOptions = [
        CURLOPT_URL            => $url,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $postFields,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER         => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS      => 5,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_USERAGENT      => 'MyApp/1.0',
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/x-www-form-urlencoded',
            // 'Content-Type: application/json', // 若送 JSON
        ],
    ];
    curl_setopt_array($ch, array_merge($defaultOptions, $options));
    $response = curl_exec($ch);
    if ($response === false) {
        error_log('cURL POST error: ' . curl_error($ch));
    }
    curl_close($ch);
    return $response;
}

// 使用:表單格式
$result = httpPost('https://api.example.com/messages', [
    'from'    => 1001,
    'to'      => 2002,
    'subject' => 'Hello',
    'body'    => 'World',
]);

// 使用:JSON 格式
$jsonData = json_encode(['items' => [1,2,3]]);
$result = httpPost('https://api.example.com/bulk', $jsonData, [
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($jsonData),
    ],
]);

常用選項速查表

選項說明典型值
CURLOPT_URL請求網址'https://api.example.com/endpoint'
CURLOPT_RETURNTRANSFER回傳字串而非直接輸出true
CURLOPT_HEADER包含回應標頭false
CURLOPT_FOLLOWLOCATION自動跟隨 3xx 重導向true
CURLOPT_MAXREDIRS最大重導向次數5
CURLOPT_TIMEOUT總超時(秒)10~30
CURLOPT_CONNECTTIMEOUT連線階段超時(秒)5
CURLOPT_SSL_VERIFYPEER驗證 SSL 憑證true (生產環境)
CURLOPT_SSL_VERIFYHOST驗證 CN/Subject Alt Name2
CURLOPT_CAINFO自訂 CA 憑證路徑'/path/to/cacert.pem'
CURLOPT_USERAGENTUser-Agent 標頭'MyBot/1.0'
CURLOPT_HTTPHEADER自訂請求標頭陣列['Authorization: Bearer xxx']
CURLOPT_POST啟用 POSTtrue
CURLOPT_POSTFIELDSPOST 資料 (陣列=multipart, 字串=urlencoded)http_build_query($arr)
CURLOPT_PUT / CUSTOMREQUESTPUT/DELETE/PATCH 等'PUT'
CURLOPT_COOKIEJAR/FILECookie 儲存/讀取檔案'/tmp/cookies.txt'
CURLOPT_PROXY代理伺服器'https://proxy:3128'

進階技巧

1. 取得回應標頭與狀態碼

curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

2. 多執行緒並發請求

$mh = curl_multi_init();
$handles = [];
foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $ch);
    $handles[$url] = $ch;
}
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running);
$results = [];
foreach ($handles as $url => $ch) {
    $results[$url] = curl_multi_getcontent($ch);
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);

3. 檔案上傳

$data = [
    'file' => new CURLFile('/path/to/image.jpg', 'image/jpeg', 'avatar.jpg'),
    'user_id' => 123,
];
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 自動設為 multipart/form-data

錯誤處理與除錯

$response = curl_exec($ch);
if ($response === false) {
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    // 常見錯誤碼:6=無法解析域名, 7=連線失敗, 28=逾時, 60=SSL 憑證驗證失敗
    error_log("cURL error [$errno]: $error");
    return null;
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode < 200 || $httpCode >= 300) {
    error_log("HTTP $httpCode: $response");
    return null;
}

安全與最佳實務

  • 永不關閉 SSL 驗證 (CURLOPT_SSL_VERIFYPEER => false) 於生產環境;若憑證問題,請補裝正確 CA 憑證 (CURLOPT_CAINFO)。
  • 設定合理 超時,避免阻塞進程。
  • 敏感 API 必須驗證 回應簽名/憑證指紋。
  • 重試機制:指數退避 + 亂數抖動,避免雪崩效應。
  • 記錄 請求/回應摘要 (不含敏感欄位) 供稽核。
  • 考慮使用 Guzzle、Http\Client (HTTPlug) 等高層庫,提供中介軟體、PSR-18 相容、非同步支援。

總結

cURL 是 PHP HTTP 整合的基石。掌握 curl_setopt_array 組合選項、curl_multi 並發、CURLFile 上傳、錯誤碼對應與 SSL 安全配置,即可應對絕大多數對外介接場景。現代專案建議封裝為符合 PSR-18 的 Client 介面,便於測試與替換實作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved