cURL 是 PHP 與外部服務交互的核心工具,支援 HTTP/HTTPS/FTP/IMAP/POP3/SMTP 等協議,功能遠超 `file_get_contents()`。本文涵蓋安裝啟用、基礎四步法、常用選項速查表、GET/POST/JSON/文件上傳/代理/SSL/異步並發等實戰場景完整代碼。
; php.ini
extension=curl ; 取消註釋
; Windows: extension_dir = "ext" 確認 php_curl.dll 存在
; Linux: apt/yum install php-curl && systemctl restart php-fpm
驗證:`php -m | grep curl` 或 `php -r "var_dump(curl_version());"`
<?php
// 1. 初始化
$ch = curl_init();
// 2. 設置選項 (核心)
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.example.com/users',
CURLOPT_RETURNTRANSFER => true, // 返回字串而非直接輸出
CURLOPT_HEADER => false, // 不包含響應頭
CURLOPT_TIMEOUT => 10, // 總超時秒數
CURLOPT_CONNECTTIMEOUT => 5, // 連接超時
CURLOPT_SSL_VERIFYPEER => true, // 生產環境必須驗證 SSL 證書
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_FOLLOWLOCATION => true, // 跟隨重定向
CURLOPT_MAXREDIRS => 5,
CURLOPT_USERAGENT => 'MyApp/1.0 (+https://my.com)', // 良好的公民
]);
// 3. 執行並獲取結果
$response = curl_exec($ch);
// 4. 錯誤處理
if ($response === false) {
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException("cURL Error [$errno]: $error");
}
// 5. 獲取響應信息 (可選)
$info = curl_getinfo($ch);
$httpCode = $info['http_code']; // 200, 404, 500...
// 6. 關閉釋放資源
curl_close($ch);
// 處理響應
$data = json_decode($response, true);
?>
| 場景 | 選項 | 說明 |
|---|---|---|
| 基礎 | CURLOPT_URL | 請求地址 |
| CURLOPT_RETURNTRANSFER | true 返回字串,false 直接輸出 | |
| CURLOPT_HEADER | true 包含響應頭 | |
| 超時 | CURLOPT_TIMEOUT | 整個請求最大秒數 |
| CURLOPT_CONNECTTIMEOUT | 建立連接最大秒數 | |
| CURLOPT_LOW_SPEED_LIMIT | 低速限制字節/秒 | |
| CURLOPT_LOW_SPEED_TIME | 低速持續秒數觸發中止 | |
| SSL | CURLOPT_SSL_VERIFYPEER | 驗證證書 (生產 true) |
| CURLOPT_SSL_VERIFYHOST | 2 驗證 CN 匹配域名 | |
| CURLOPT_CAINFO | 自定義 CA 憑證路徑 | |
| 代理 | CURLOPT_PROXY | 代理地址 ip:port |
| CURLOPT_PROXYTYPE | CURLPROXY_HTTP/SOCKS5 | |
| CURLOPT_PROXYUSERPWD | 代理認證 user:pwd | |
| Cookie | CURLOPT_COOKIE | 發送 Cookie 字串 |
| CURLOPT_COOKIEJAR | 保存響應 Cookie 到文件 | |
| CURLOPT_COOKIEFILE | 從文件讀取 Cookie 發送 | |
| 認證 | CURLOPT_USERPWD | Basic Auth "user:pwd" |
| CURLOPT_HTTPAUTH | CURLAUTH_BASIC/DIGEST/BEARER | |
| CURLOPT_BEARER | Bearer Token (PHP 7.1+) |
| 錯誤碼 | 常量 | 典型原因 |
|---|---|---|
| 6 | CURLE_COULDNT_RESOLVE_HOST | DNS 解析失敗 |
| 7 | CURLE_COULDNT_CONNECT | 連接被拒/防火牆/端口錯誤 |
| 28 | CURLE_OPERATION_TIMEDOUT | 超時 (調大 TIMEOUT/CONNECTTIMEOUT) |
| 35 | CURLE_SSL_CONNECT_ERROR | SSL 握手失敗 (證書過期/不信任/協議版本) |
| 51 | CURLE_SSL_PEER_CERTIFICATE | 證書驗證失敗 (CA 不匹配/自簽名) |
| 60 | CURLE_SSL_CACERT | CA 證書文件找不到/格式錯誤 |
<?php
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_VERBOSE => true, // 輸出詳細通訊過程
CURLOPT_STDERR => fopen('php://temp', 'rw'), // 捕獲到變量
CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
rewind($verbose = curl_getinfo($ch, CURLINFO_HEADER_OUT)); // 不對,正確捕獲:
// 正確捕獲 VERBOSE 輸出:
$verboseHandle = fopen('php://temp', 'rw');
curl_setopt($ch, CURLOPT_STDERR, $verboseHandle);
curl_exec($ch);
rewind($verboseHandle);
$verboseLog = stream_get_contents($verboseHandle);
fclose($verboseHandle);
error_log($verboseLog); // 記錄到日誌分析
?>