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

PHP cURL 库完整指南:從初始化到模擬登錄的實戰詳解

     編輯:PHP 綜合知識

cURL 簡介

cURL (Client URL Library) 是 PHP 中功能最強大的網絡請求庫,支援 HTTP/HTTPS、FTP、代理、Cookie、認證、斷點續傳等幾乎所有網絡場景。無論是抓取網頁、調用 API、模擬登錄、還是文件上傳,cURL 都是首選工具。

核心函數速查表

函數用途
curl_init()初始化會話,返回句柄
curl_setopt()設置單個選項
curl_setopt_array()批量設置選項(推薦)
curl_exec()執行請求,返回響應
curl_close()關閉會話,釋放資源
curl_getinfo()獲取請求詳情(狀態碼、耗時等)
curl_error() / curl_errno()獲取錯誤信息
curl_multi_*並發多請求系列函數

三大核心步驟

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

// 2. 配置選項(至少設置 URL)
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回字符串而非直接輸出

// 3. 執行並關閉
$response = curl_exec($ch);
if ($response === false) {
    throw new Exception(curl_error($ch), curl_errno($ch));
}
curl_close($ch);

// 4. 後續處理
$data = json_decode($response, true);
?>

四大經典實戰場景

場景一:基礎 GET 請求

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://www.example.com',
    CURLOPT_HEADER         => true,        // 包含響應頭
    CURLOPT_RETURNTRANSFER => true,        // 返回字符串
    CURLOPT_TIMEOUT        => 10,          // 超時秒數
    CURLOPT_USERAGENT      => 'Mozilla/5.0 (compatible; MyBot/1.0)',
]);
$data = curl_exec($ch);
curl_close($ch);
var_dump($data);
?>

場景二:POST 表單提交

<?php
$postData = [
    'phone'   => '13800138000',
    'message' => 'Hello from cURL',
];
$ch = curl_init('https://api.example.com/send');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($postData), // 關鍵:用 http_build_query 而非數組
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/x-www-form-urlencoded'],
]);
$result = curl_exec($ch);
curl_close($ch);
?>

避坑:直接傳數組給 CURLOPT_POSTFIELDS 會發送 multipart/form-data,導致對方 $_POST 為空。必須用 http_build_query() 轉為 URL 編碼字符串。

場景三:代理請求

<?php
$ch = curl_init('https://httpbin.org/ip');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER   => true,
    CURLOPT_HTTPPROXYTUNNEL  => true,
    CURLOPT_PROXY            => 'proxy.example.com:8080',
    CURLOPT_PROXYUSERPWD     => 'username:password', // 如需認證
    CURLOPT_PROXYTYPE        => CURLPROXY_HTTP,      // 或 SOCKS5
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response; // 顯示代理 IP
?>

場景四:模擬登錄並保持 Session(以 Discuz 為例)

<?php
// 1. 獲取登錄頁,提取 formhash
$ch = curl_init('https://bbs.example.com/member.php?mod=logging&action=login');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEJAR      => 'cookie.txt', // 保存 Cookie
    CURLOPT_COOKIEFILE     => 'cookie.txt', // 讀取 Cookie
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_SSL_VERIFYPEER => false,        // 測試環境可關閉 SSL 驗證
]);
$loginPage = curl_exec($ch);

// 解析 formhash(實際選擇器需根據目標站點調整)
preg_match('/name="formhash" value="([^"]+)"/', $loginPage, $m);
$formhash = $m[1] ?? '';
curl_close($ch);

// 2. 提交登錄表單
$postFields = [
    'formhash'    => $formhash,
    'referer'     => 'https://bbs.example.com/',
    'username'    => 'your_username',
    'password'    => 'your_password',
    'loginsubmit' => 'true',
];
$ch = curl_init('https://bbs.example.com/member.php?mod=logging&action=login&loginsubmit=yes');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($postFields),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEJAR      => 'cookie.txt',
    CURLOPT_COOKIEFILE     => 'cookie.txt',
    CURLOPT_REFERER        => 'https://bbs.example.com/member.php?mod=logging&action=login',
]);
curl_exec($ch);
curl_close($ch);

// 3. 攜帶 Cookie 訪問需登錄頁面
$ch = curl_init('https://bbs.example.com/home.php?mod=spacecp');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEFILE     => 'cookie.txt',
]);
$profile = curl_exec($ch);
curl_close($ch);
echo $profile;
?>

高階技巧與最佳實踐

1. 超時精確控制

curl_setopt_array($ch, [
    CURLOPT_CONNECTTIMEOUT_MS => 500,   // 連接階段 500ms
    CURLOPT_TIMEOUT_MS         => 5000, // 整個請求 5s
    CURLOPT_NOSIGNAL           => true, // 多線程環境必須開啟
]);

2. 自定義請求頭與 User-Agent

curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Accept: application/json',
    'Authorization: Bearer ' . $token,
    'X-Requested-With: XMLHttpRequest',
]);

3. 並發請求:curl_multi_* 系列

需同時抓取多個 URL 時,使用 curl_multi_init 可顯著提升吞吐量,代碼模式:

$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 > 0);
foreach ($handles as $url => $ch) {
    $responses[$url] = curl_multi_getcontent($ch);
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);

4. 錯誤處理標準模式

$response = curl_exec($ch);
if ($response === false) {
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    // 記錄日誌、拋異常、重試邏輯...
    throw new RuntimeException("cURL error ($errno): $error");
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 400) {
    throw new HttpException("HTTP $httpCode", $httpCode, $response);
}

常見問題排查

  • SSL 證書驗證失敗:生產環境請配置 CURLOPT_CAINFO 指向有效 CA 憑證包,勿長期使用 CURLOPT_SSL_VERIFYPEER => false
  • 中文亂碼:確保請求頭含 Accept-Charset: utf-8,響應用 mb_convert_encoding 處理
  • 重定向循環:設置 CURLOPT_MAXREDIRS => 10 限制跳轉次數
  • 大文件下載:用 CURLOPT_WRITEFUNCTION 回調流式寫入磁盤,避免內存溢出
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved