在 PHP 開發中,cURL 是進行 HTTP 請求的核心工具。雖然原生 cURL 函數功能強大,但直接使用往往代碼冗長、參數配置繁瑣。本文將介紹兩款實用的 PHP cURL 封裝類,幫助開發者輕鬆應對各種網絡請求場景,從基礎的 GET/POST 到複雜的 Header 設定、Cookie 管理、代理 IP 偽裝等高級功能。
在使用封裝類之前,必須確保 PHP 環境已正確載入 cURL 模組。Windows 環境下的啟用步驟如下:
php.ini,找到 ;extension=php_curl.dll 並移除前面的分號libeay32.dll、ssleay32.dll、php5ts.dll、php_curl.dll 複製到系統目錄 C:\Windows\ 下可通過 phpinfo() 檢查 curl 區塊是否出現,確認擴展已成功載入。
這款封裝類採用陣列方式傳遞所有 cURL 選項,靈活度極高,適合需要精細控制請求參數的場景。
<?php
class Curl
{
public $cookieFile;
public $timeout = 160;
public function __construct($dir)
{
$this->cookieFile = $this->getTemporaryCookieFileName($dir);
}
/**
* 發送請求並獲取響應內容
* @param array $curlOptions cURL 選項陣列
* @return string|false 成功返回響應字符串,失敗返回 false
*/
public function getResponseText($curlOptions)
{
// 確保返回字符串而非直接輸出
if (!isset($curlOptions[CURLOPT_RETURNTRANSFER]) || $curlOptions[CURLOPT_RETURNTRANSFER] === false) {
$curlOptions[CURLOPT_RETURNTRANSFER] = true;
}
$curl = curl_init();
curl_setopt_array($curl, $curlOptions);
$responseText = '';
try {
$responseText = curl_exec($curl);
if (($errno = curl_errno($curl)) !== CURLE_OK) {
$errmsg = curl_error($curl);
throw new Exception($errmsg, $errno);
}
} catch (Exception $e) {
$responseText = false;
}
curl_close($curl);
return $responseText;
}
/**
* Unicode 轉 UTF-8 工具方法
*/
public function unicodeToUtf8($string)
{
$string = str_replace('u', '', strtolower($string));
$length = strlen($string) / 4;
$stringResult = '';
for ($i = 0; $i < $length; $i++) {
$charUnicodeHex = substr($string, $i * 4, 4);
$unicodeCode = hexdec($charUnicodeHex);
$utf8Code = '';
if ($unicodeCode < 128) {
$utf8Code = chr($unicodeCode);
} elseif ($unicodeCode < 2048) {
$utf8Code .= chr(192 + (($unicodeCode - ($unicodeCode % 64)) / 64));
$utf8Code .= chr(128 + ($unicodeCode % 64));
} else {
$utf8Code .= chr(224 + (($unicodeCode - ($unicodeCode % 4096)) / 4096));
$utf8Code .= chr(128 + ((($unicodeCode % 4096) - ($unicodeCode % 64)) / 64));
$utf8Code .= chr(128 + ($unicodeCode % 64));
}
$stringResult .= $utf8Code;
}
return $stringResult;
}
private function getTemporaryCookieFileName($dir = '.')
{
return str_replace('\\', '/', tempnam($dir, 'tmp'));
}
}
?>
<?php
include_once('curl.class.php');
$aa = new Curl('');
$curlOptions = array(
CURLOPT_URL => "https://www.example.com/addTicket.jsp",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_REFERER => "https://www.example.com/referer",
CURLOPT_HTTPHEADER => array(
'X-FORWARDED-FOR: 139.197.14.19',
'CLIENT-IP: 127.0.0.1',
'Proxy-Client-IP: 139.197.14.19',
'WL-Proxy-Client-IP: 139.197.14.19'
),
CURLOPT_HEADER => 1,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => 'ids=897&Submit=%E6%8A%95%E7%A5%A8',
CURLOPT_TIMEOUT => $aa->timeout
);
echo $aa->getResponseText($curlOptions);
?>
關鍵特性:
這款封裝類提供 get()、post()、put() 等語義化方法,代碼更易讀,適合快速開發常規 API 請求。
<?php
class Curl
{
function __construct() { return true; }
function execute($method, $url, $fields = '', $userAgent = '', $httpHeaders = '', $username = '', $password = '')
{
$ch = self::create();
if ($ch === false) return false;
if (!is_string($url) || !strlen($url)) return false;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($username !== '') {
curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
}
$method = strtolower($method);
if ('post' === $method) {
curl_setopt($ch, CURLOPT_POST, true);
if (is_array($fields)) {
$sets = array();
foreach ($fields as $key => $val) {
$sets[] = $key . '=' . urlencode($val);
}
$fields = implode('&', $sets);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
} elseif ('put' === $method) {
curl_setopt($ch, CURLOPT_PUT, true);
}
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
if (strlen($userAgent)) {
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
}
if (is_array($httpHeaders)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeaders);
}
$ret = curl_exec($ch);
if (curl_errno($ch)) {
$err = array(curl_error($ch), curl_errno($ch));
curl_close($ch);
return $err;
} else {
curl_close($ch);
if (!is_string($ret) || !strlen($ret)) return false;
return $ret;
}
}
function post($url, $fields, $userAgent = '', $httpHeaders = '', $username = '', $password = '')
{
$ret = self::execute('POST', $url, $fields, $userAgent, $httpHeaders, $username, $password);
return ($ret === false || is_array($ret)) ? false : $ret;
}
function get($url, $userAgent = '', $httpHeaders = '', $username = '', $password = '')
{
$ret = self::execute('GET', $url, '', $userAgent, $httpHeaders, $username, $password);
return ($ret === false || is_array($ret)) ? false : $ret;
}
function create()
{
if (!function_exists('curl_init')) return false;
$ch = curl_init();
return is_resource($ch) ? $ch : false;
}
}
?>
<?php
$curl = new Curl();
// GET 請求
$response = $curl->get('https://www.example.com/');
// POST 請求
$response = $curl->post('https://www.example.com/api', 'param1=value1¶m2=value2');
// 帶 Header 的 POST
$headers = array('Content-Type: application/json', 'Authorization: Bearer token123');
$response = $curl->post('https://www.example.com/api', json_encode($data), '', $headers);
?>
優勢:
| 特性 | 封裝類一(選項陣列) | 封裝類二(語義化方法) |
|---|---|---|
| 靈活度 | 極高,支援所有 cURL 選項 | 中等,封裝常用場景 |
| 代碼可讀性 | 需熟悉 cURL 選項常量 | 高,方法名語義清晰 |
| 適用場景 | 複雜請求、特殊 Header、代理、SSL 設定 | 常規 REST API、快速原型開發 |
| Cookie 管理 | 內建臨時文件自動管理 | 需自行擴展 |
| 錯誤處理 | try-catch 異常捕獲 | 返回 false 或錯誤陣列 |
CURLOPT_TIMEOUT 和 CURLOPT_CONNECTTIMEOUT,防止請求無限等待CURLOPT_SSL_VERIFYPEER,生產環境建議配置 CA 憑證啟用驗證CURLOPT_TCP_KEEPALIVE 或使用 cURL 多工cURL 封裝類能顯著提升 PHP 網絡請求的開發效率與代碼維護性。封裝類一適合需要精細控制的複雜場景,封裝類二適合日常 API 對接。根據項目需求選擇合適的封裝,並遵循最佳實踐,即可構建健壯的 HTTP 客戶端。