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

PHP cURL 介接 API 完整指南:從基礎到進階實戰

     編輯:PHP 相關知識

cURL 基礎流程

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

// 2. 設定選項
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://api.example.com/endpoint',
    CURLOPT_RETURNTRANSFER => true,      // 回傳字串而非直接輸出
    CURLOPT_POST           => true,      // POST 請求
    CURLOPT_POSTFIELDS     => http_build_query(['key' => 'value']), // 表單資料
    CURLOPT_HTTPHEADER     => [
        'Content-Type: application/x-www-form-urlencoded',
        'Authorization: Bearer ' . $token,
    ],
    CURLOPT_TIMEOUT        => 30,        // 總超時秒數
    CURLOPT_CONNECTTIMEOUT => 10,        // 連線超時秒數
    CURLOPT_SSL_VERIFYPEER => true,      // 驗證 SSL 憑證
    CURLOPT_FOLLOWLOCATION => true,      // 支援重導向
    CURLOPT_MAXREDIRS      => 5,         // 最大重導向次數
]);

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

// 4. 錯誤檢查
if ($response === false) {
    $errorNo = curl_errno($ch);
    $errorMsg = curl_error($ch);
    throw new Exception("cURL 錯誤 ($errorNo): $errorMsg");
}

// 5. 取得 HTTP 狀態碼
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// 6. 關閉
curl_close($ch);

// 7. 處理回應
$data = json_decode($response, true);

常用選項分類速查

類別選項說明
URL/請求CURLOPT_URL請求網址
CURLOPT_CUSTOMREQUEST自訂 HTTP 方法 (GET/POST/PUT/DELETE/PATCH)
CURLOPT_POST是否 POST
CURLOPT_POSTFIELDSPOST 資料 (陣列=multipart, 字串=urlencoded)
標頭CURLOPT_HTTPHEADER請求標頭陣列
CURLOPT_USERAGENTUser-Agent 字串
CURLOPT_REFERERReferer 標頭
CURLOPT_COOKIECookie 字串
回應處理CURLOPT_RETURNTRANSFER回傳字串 (必設 true)
CURLOPT_HEADER包含回應標頭在輸出中
CURLOPT_WRITEFUNCTION自訂寫入回呼 (流式處理大檔案)
CURLOPT_FILE直接寫入檔案資源
SSL/安全CURLOPT_SSL_VERIFYPEER驗證對方憑證 (生產必開 true)
CURLOPT_SSL_VERIFYHOST驗證 CN (2=嚴格)
CURLOPT_CAINFOCA 憑證束路徑
CURLOPT_SSLCERT客戶端憑證 (.pem)
超時/限制CURLOPT_TIMEOUT總超時 (秒)
CURLOPT_CONNECTTIMEOUT連線超時 (秒)
CURLOPT_LOW_SPEED_LIMIT低速門檻 (bytes/sec)
CURLOPT_LOW_SPEED_TIME低速持續秒數才中斷
代理/連線CURLOPT_PROXY代理伺服器
CURLOPT_PROXYUSERPWD代理認證
CURLOPT_INTERFACE指定網卡 IP

進階實戰場景

1. JSON API 請求

<?php
$payload = json_encode(['user_id' => 123, 'action' => 'purchase']);

$ch = curl_init('https://api.example.com/order');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS    => $payload,
    CURLOPT_HTTPHEADER    => [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($payload),
        'Authorization: Bearer ' . $accessToken,
    ],
    CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);

2. 檔案上傳

<?php
$filePath = '/path/to/image.jpg';
$postFields = [
    'file' => new CURLFile($filePath, 'image/jpeg', 'image.jpg'),  // PHP 5.5+
    'user_id' => 123,
];

$ch = curl_init('https://api.example.com/upload');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $postFields,
    CURLOPT_RETURNTRANSFER => true,
]);

3. 斷點續傳下載大檔案

<?php
$url = 'https://example.com/large-file.zip';
$savePath = '/data/large-file.zip';

$fp = fopen($savePath, 'ab');  // 追加模式
$downloaded = filesize($savePath) ?: 0;

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RANGE => "$downloaded-",  // 從已下載位置繼續
    CURLOPT_FILE => $fp,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT => 0,  // 不限制總時間
]);
curl_exec($ch);
fclose($fp);

4. 並發請求

<?php
$urls = [
    'https://api1.example.com/data',
    'https://api2.example.com/data',
    'https://api3.example.com/data',
];

$mh = curl_multi_init();
$handles = [];

foreach ($urls as $i => $url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
    ]);
    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] = [
        'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
        'body' => curl_multi_getcontent($ch),
        'error' => curl_error($ch),
    ];
    curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);

5. 自動處理 Cookie(模擬登入)

<?php
$cookieJar = '/tmp/cookies.txt';

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_COOKIEJAR  => $cookieJar,  // 儲存回應 Cookie
    CURLOPT_COOKIEFILE => $cookieJar,  // 發送儲存的 Cookie
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
]);

// 1. 登入
curl_setopt($ch, CURLOPT_URL, 'https://example.com/login');
curl_setopt($ch, CURLOPT_POSTFIELDS, ['user' => 'xxx', 'pass' => 'yyy']);
curl_exec($ch);

// 2. 存取需登入頁面 (自動攜帶 Cookie)
curl_setopt($ch, CURLOPT_URL, 'https://example.com/dashboard');
$dashboard = curl_exec($ch);

錯誤碼對照表

代碼常數說明
6CURLE_COULDNT_RESOLVE_HOSTDNS 解析失敗
7CURLE_COULDNT_CONNECT無法連線到主機
28CURLE_OPERATION_TIMEDOUT操作逾時
35CURLE_SSL_CONNECT_ERRORSSL 連線錯誤
51CURLE_SSL_PEER_CERTIFICATE對方憑證驗證失敗
60CURLE_SSL_CACERTCA 憑證驗證失敗
22CURLE_HTTP_RETURNED_ERRORHTTP 狀態碼 >= 400 (需配合 CURLOPT_FAILONERROR)

最佳實踐檢查清單

  • ✅ 生產環境 啟用 SSL 驗證 (CURLOPT_SSL_VERIFYPEER = true)
  • ✅ 設定 合理超時 (連線 5-10s,總計 30-60s)
  • ✅ 檢查 HTTP 狀態碼 而非只看回應內容
  • ✅ 使用 http_build_query 編碼表單資料,避免手工拼接
  • ✅ 大檔案使用 CURLOPT_FILE 或 CURLOPT_WRITEFUNCTION 避免記憶體暴增
  • ✅ 重試機制:指數退避 + 最大重試次數 (針對 5xx、網路錯誤)
  • ✅ 記錄請求/回應日誌 (含耗時、狀態碼、錯誤) 利於除錯
  • ✅ 敏感資訊 (Token、密鑰) 不寫入日誌
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved