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

PHP cURL 初始化與使用詳解:從基礎到高級實戰

     編輯:PHP 相關知識

PHP cURL 操作指南:環境配置、核心函數、實戰封裝與避坑

cURL 是 PHP 進行 HTTP 請求(API 調用、爬蟲、文件上傳/下載)的核心擴展。本文覆蓋安裝驗證、基礎流程、常用選項、高級場景封裝及常見錯誤排查。

一、環境安裝與驗證

  • Linux:yum/dnf/apt install php-curl → 重啟 PHP-FPM/Apache。
  • Windows:`php.ini` 取消註釋 extension=curl,確保 `libssh2.dll`、`libeay32.dll`、`ssleay32.dll` 在系統 PATH (PHP 目錄) 下 → 重啟 Web 服務器。
  • 驗證:php -m | grep curl 或 `phpinfo()` 搜 `curl support => enabled`。

二、基礎請求流程 (四步走)

<?php
// 1. 初始化
$ch = curl_init();
if ($ch === false) die('cURL 初始化失敗: ' . curl_error($ch));

// 2. 設置選項 (核心)
$url = 'https://api.example.com/users';
curl_setopt_array($ch, [
    CURLOPT_URL            => $url,           // 目標 URL
    CURLOPT_RETURNTRANSFER => true,           // **關鍵**:返回字符串而非直接輸出
    CURLOPT_HEADER         => false,          // 不包含響應頭
    CURLOPT_FOLLOWLOCATION => true,           // 自動跟隨 301/302 跳轉
    CURLOPT_MAXREDIRS      => 5,              // 最大跳轉次數
    CURLOPT_TIMEOUT        => 10,             // 總超時秒數
    CURLOPT_CONNECTTIMEOUT => 5,              // 連接超時
    CURLOPT_SSL_VERIFYPEER => true,           // **生產必開**:驗證 SSL 證書
    CURLOPT_SSL_VERIFYHOST => 2,              // 驗證域名匹配
    // CURLOPT_CAINFO       => '/path/to/cacert.pem', // 自定義 CA 憑證路徑
    CURLOPT_USERAGENT      => 'MyApp/1.0 (+https://example.com)', // 標識爬蟲身份
]);

// 3. 執行請求
$response = curl_exec($ch);
$errno    = curl_errno($ch);
$error    = curl_error($ch);
$info     = curl_getinfo($ch); // 獲取 HTTP 碼、耗時、大小等元數據

// 4. 關閉釋放
curl_close($ch);

// 處理結果
if ($errno) {
    error_log("cURL 錯誤 [$errno]: $error | URL: $url");
    // 重試邏輯...
} else {
    $httpCode = $info['http_code'];
    if ($httpCode >= 200 && $httpCode < 300) {
        $data = json_decode($response, true); // 假設 JSON 響應
        // 業務處理...
    } else {
        error_log("HTTP 錯誤 [$httpCode]: $response");
    }
}
?>

三、高頻場景封裝類

<?php
class HttpClient {
    private $ch;
    private $defaultOpts = [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER         => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS      => 3,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_USERAGENT      => 'HttpClient/1.0',
    ];

    public function __construct() {
        $this->ch = curl_init();
        if (!$this->ch) throw new Exception('cURL 初始化失敗');
        curl_setopt_array($this->ch, $this->defaultOpts);
    }

    public function __destruct() {
        if ($this->ch) curl_close($this->ch);
    }

    // 通用請求
    public function request(string $method, string $url, array $data = [], array $headers = []): array {
        $opts = [
            CURLOPT_URL            => $url,
            CURLOPT_CUSTOMREQUEST  => strtoupper($method),
        ];
        
        if (in_array($method, ['POST', 'PUT', 'PATCH'])) {
            $opts[CURLOPT_POSTFIELDS] = is_array($data) ? http_build_query($data) : $data;
            $headers[] = 'Content-Type: application/x-www-form-urlencoded';
        }
        
        if ($headers) {
            $opts[CURLOPT_HTTPHEADER] = $headers;
        }
        
        curl_setopt_array($this->ch, $opts);
        $response = curl_exec($this->ch);
        $errno = curl_errno($this->ch);
        $error = curl_error($this->ch);
        $info = curl_getinfo($this->ch);
        
        // 重置選項供下次復用 (重要!)
        curl_setopt_array($this->ch, $this->defaultOpts);
        
        return [
            'success'   => $errno === 0 && ($info['http_code'] >= 200 && $info['http_code'] < 300),
            'http_code' => $info['http_code'],
            'body'      => $response,
            'error'     => $errno ? "cURL $errno: $error" : null,
            'info'      => $info,
        ];
    }

    // 便捷方法
    public function get(string $url, array $params = [], array $headers = []): array {
        if ($params) $url .= (strpos($url, '?') ? '&' : '?') . http_build_query($params);
        return $this->request('GET', $url, [], $headers);
    }
    public function post(string $url, array $data = [], array $headers = []): array { return $this->request('POST', $url, $data, $headers); }
    public function postJson(string $url, array $data = [], array $headers = []): array {
        $headers[] = 'Content-Type: application/json';
        return $this->request('POST', $url, json_encode($data), $headers);
    }
}

// 使用示例
$client = new HttpClient();
$res = $client->postJson('https://api.example.com/order', ['goods_id' => 101, 'num' => 2]);
if ($res['success']) {
    echo "下單成功: " . json_encode($res['body']);
} else {
    echo "失敗: " . $res['error'];
}
?>

四、常見問題排查表

現象原因解決
返回 bool(false) / 空白未設置 CURLOPT_RETURNTRANSFER => true必加此選項
SSL certificate problemCA 憑證缺失/過期/自簽名下載 cacert.pem 配置 CURLOPT_CAINFO;內網測試暫時關閉驗證 (生產禁用)
Connection timed out防火牆/安全組/目標 IP 錯誤/超時太短檢查網絡通達性、調大 CURLOPT_TIMEOUT
HTTP 400/405請求方法/參數格式/Content-Type 不符抓包對比文檔、確認 http_build_query vs json_encode
中文亂碼編碼不一致確保 URL 編碼 `urlencode`、POST 數據 UTF-8、設置 `Accept-Charset: UTF-8`
內存耗盡下載大文件未流式處理用 CURLOPT_WRITEFUNCTION 回調寫入文件句柄

五、進階技巧

  • 並發請求:`curl_multi_init()` 批量並發,大幅提升爬蟲/聚合 API 效率。
  • 斷點續傳/大文件下載:`CURLOPT_RANGE` + `CURLOPT_WRITEFUNCTION` 寫入文件句柄。
  • 代理/IP 池:`CURLOPT_PROXY`、`CURLOPT_PROXYUSERPWD` 配合驗證代理。
  • Cookie 會話保持:`CURLOPT_COOKIEJAR` (保存) / `CURLOPT_COOKIEFILE` (讀取) 同一文件路徑。
  • 性能分析:`curl_getinfo($ch, CURLINFO_TOTAL_TIME)` 等細粒度耗時指標優化瓶頸。

總結

cURL 是 PHP 網絡編程的瑞士軍刀。**務必開啟 `RETURNTRANSFER`、生產環境堅持 `SSL_VERIFYPEER=true`、封裝復用類管理句柄生命周期、善用 `curl_getinfo` 觀測性能**。現代項目亦可考慮 Guzzle (PSR-18 標準客戶端) 獲得更優雅的異步、中間件、重試機制。

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