模擬登入核心在於**會話保持**(Cookie 文件複用)與**請求偽裝**(User-Agent、Referer、Header)。本文提供一個可直接落地的封裝類,支援驗證碼圖片預取 Cookie、POST 表單提交、302 重定向跟隨、SSL 忽略(僅測試環境)。
<?php
class CurlSimulator {
private $cookieFile;
private $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36';
private $defaultHeaders = [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8',
'Connection: keep-alive',
];
public function __construct($cookieDir = '') {
$this->cookieFile = ($cookieDir ?: sys_get_temp_dir()) . '/curl_cookie_' . md5(microtime(true)) . '.txt';
}
/** 獲取初始 Cookie(如驗證碼頁面) */
public function fetchCookie($url) {
$ch = $this->initCurl($url);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookieFile); // 保存 Cookie
curl_exec($ch);
curl_close($ch);
}
/** 提交登入表單 */
public function login($url, array $postData, array $extraHeaders = []) {
$ch = $this->initCurl($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookieFile); // 發送 Cookie
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($this->defaultHeaders, $extraHeaders));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟隨 302
$response = curl_exec($ch);
$errno = curl_errno($ch);
curl_close($ch);
if ($errno) throw new \RuntimeException("cURL error [$errno]: " . curl_error($ch));
return $response;
}
private function initCurl($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 僅測試環境
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HEADER, false);
return $ch;
}
public function __destruct() {
if (file_exists($this->cookieFile)) @unlink($this->cookieFile); // 可選:銷毀時清理
}
}
$sim = new CurlSimulator();
// 1. 先訪問登入頁/驗證碼接口,建立 Cookie
$sim->fetchCookie('https://example.com/login');
// 2. 若有驗證碼,需下載圖片 -> OCR/人工識別 -> 填入 $postData['captcha']
// $captchaImg = $sim->get('https://example.com/captcha.jpg'); // 需擴展 get() 方法
// 3. 提交登入
$postData = [
'username' => 'your_account',
'password' => 'your_password',
// 'captcha' => $captchaCode,
];
$html = $sim->login('https://example.com/do_login', $postData, [
'Referer: https://example.com/login',
'Origin: https://example.com',
]);
// 4. 解析 $html 判斷是否登入成功,後續請求複用 $sim 實例即自動攜帶 Cookie
sys_get_temp_dir() 避免權限問題。http_build_query() 自動處理 application/x-www-form-urlencoded;若需 multipart/form-data(上傳文件),傳入 CURLFile 對象數組且**不**用 http_build_query。tesseract-ocr 或第三方打碼平台;複雜滑塊/點選驗證碼建議改用 Selenium/Playwright 瀏覽器自動化。CURLOPT_CAINFO 指向 cacert.pem,不可長期關閉驗證。掌握 cURL 模擬登入精髓,配合穩健的異常處理與日誌記錄,即可構建高可用的數據採集、API 聚合、自動化測試系統。