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

PHP cURL 實戰指南:從基礎抓取到進階應用場景

     編輯:PHP 綜合知識

cURL 四步走核心流程

// 1. 初始化
$ch = curl_init();

// 2. 設定選項(核心:100+ 選項組合)
curl_setopt_array($ch, [
    CURLOPT_URL => 'https://api.example.com/data',
    CURLOPT_RETURNTRANSFER => true,      // 關鍵:返回字串而非直接輸出
    CURLOPT_TIMEOUT => 10,               // 連線超時秒數
    CURLOPT_CONNECTTIMEOUT => 5,         // 建立連線超時
    CURLOPT_SSL_VERIFYPEER => false,     // 開發環境跳過證書驗證
    CURLOPT_FOLLOWLOCATION => true,      // 支援 3xx 重導向
    CURLOPT_MAXREDIRS => 5,              // 最大重導向次數
    CURLOPT_USERAGENT => 'MyApp/1.0',    // 自定義 UA
    CURLOPT_HTTPHEADER => [              // 自定義 Header
        'Accept: application/json',
        'Authorization: Bearer ' . $token,
    ],
]);

// 3. 執行
$response = curl_exec($ch);

// 4. 錯誤處理與關閉
if ($response === false) {
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    throw new Exception("cURL Error [$errno]: $error");
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

場景一:GET 請求抓取頁面/JSON

function httpGet($url, array $headers = [], $timeout = 10) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $timeout,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_SSL_VERIFYPEER => false,
    ]);
    $resp = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
    return ['body' => $resp, 'code' => $info['http_code'], 'info' => $info];
}

// 使用
$result = httpGet('https://httpbin.org/get', ['Accept: application/json']);
if ($result['code'] === 200) {
    $data = json_decode($result['body'], true);
}

場景二:POST 表單 / JSON 提交

function httpPost($url, $data, $isJson = true, $headers = []) {
    $ch = curl_init($url);
    $opts = [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
    ];
    
    if ($isJson) {
        $opts[CURLOPT_POSTFIELDS] = json_encode($data);
        $opts[CURLOPT_HTTPHEADER] = array_merge(['Content-Type: application/json'], $headers);
    } else {
        $opts[CURLOPT_POSTFIELDS] = http_build_query($data);
        $opts[CURLOPT_HTTPHEADER] = array_merge(['Content-Type: application/x-www-form-urlencoded'], $headers);
    }
    
    curl_setopt_array($ch, $opts);
    $resp = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ['body' => $resp, 'code' => $code];
}

場景三:檔案上傳

function uploadFile($url, $filePath, $fieldName = 'file', $extraFields = []) {
    $ch = curl_init($url);
    
    // PHP 5.5+ 使用 CURLFile
    $postData = [$fieldName => new CURLFile($filePath)];
    $postData = array_merge($postData, $extraFields);
    
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $postData,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 60,  // 上傳需更長超時
    ]);
    
    return curl_exec($ch);
}

場景四:模擬登入 + Cookie 維持

$cookieJar = sys_get_temp_dir() . '/cookies_' . md5($domain) . '.txt';

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_COOKIEJAR => $cookieJar,      // 儲存 Cookie
    CURLOPT_COOKIEFILE => $cookieJar,     // 讀取 Cookie
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false,
]);

// 1. 訪問登入頁(獲取 CSRF Token 等)
curl_setopt($ch, CURLOPT_URL, 'https://site.com/login');
$loginPage = curl_exec($ch);

// 2. 解析表單、提交登入
$postData = ['username' => $user, 'password' => $pass, '_token' => $csrf];
curl_setopt($ch, CURLOPT_URL, 'https://site.com/login');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_exec($ch);

// 3. 後續請求自動攜帶 Cookie
curl_setopt($ch, CURLOPT_URL, 'https://site.com/dashboard');
curl_setopt($ch, CURLOPT_POST, false);
$dashboard = curl_exec($ch);

場景五:並發請求

function multiRequest(array $urls, $options = []) {
    $mh = curl_multi_init();
    $handles = [];
    
    foreach ($urls as $i => $url) {
        $ch = curl_init($url);
        curl_setopt_array($ch, array_merge([
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => false,
        ], $options));
        curl_multi_add_handle($mh, $ch);
        $handles[$i] = $ch;
    }
    
    $running = null;
    do {
        curl_multi_exec($mh, $running);
        curl_multi_select($mh, 0.5);  // 等待活動
    } while ($running > 0);
    
    $results = [];
    foreach ($handles as $i => $ch) {
        $results[$i] = [
            'body' => curl_multi_getcontent($ch),
            'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
            'error' => curl_error($ch),
        ];
        curl_multi_remove_handle($mh, $ch);
        curl_close($ch);
    }
    curl_multi_close($mh);
    return $results;
}

// 使用:同時抓取 10 個 API
$urls = array_map(fn($id) => "https://api.example.com/item/$id", range(1, 10));
$results = multiRequest($urls);

關鍵選項速查表

選項用途常用值
CURLOPT_RETURNTRANSFER返回字串而非直接輸出true
CURLOPT_POSTFIELDSPOST 資料(陣列=multipart,字串=urlencoded/json)http_build_query($data)
CURLOPT_HTTPHEADER自定義請求 Header['Authorization: Bearer xxx']
CURLOPT_USERAGENTUser-Agent 字串'MyBot/1.0'
CURLOPT_COOKIEJAR/FILECookie 持久化檔案/tmp/cookies.txt
CURLOPT_FOLLOWLOCATION自動跟隨重導向true
CURLOPT_SSL_VERIFYPEER驗證 SSL 證書false(開發) / true(生產)
CURLOPT_TIMEOUT最大執行秒數30
CURLOPT_CONNECTTIMEOUT連線建立超時10
CURLOPT_PROXY代理伺服器'https://proxy:8080'

錯誤處理最佳實踐

function safeCurlExec($ch) {
    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    
    if ($errno) {
        $error = curl_error($ch);
        // 記錄詳細資訊便於除錯
        $info = curl_getinfo($ch);
        error_log("cURL [$errno] $error | URL: {$info['url']} | IP: {$info['primary_ip']}");
        return false;
    }
    
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if ($httpCode >= 400) {
        error_log("HTTP $httpCode: " . substr($response, 0, 500));
    }
    return $response;
}

總結

cURL 是 PHP 最強大的 HTTP 客戶端。掌握 curl_setopt_array 批次設定、CURLFile 檔案上傳、CookieJar 狀態維持、curl_multi 並發請求四大核心技能,可覆蓋 95% 的對外整合場景。生產環境務必啟用 SSL 驗證、設定合理超時、記錄完整錯誤日誌。

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