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

PHP 中 cURL 與 file_get_contents 深度對比與選型指南

     編輯:PHP 綜合知識

為什麼不再滿足於 file_get_contents?

在開發網頁採集器專案時,我深刻體會到 file_get_contents 的局限性。雖然它語法簡潔、調用便捷,但面對複雜的網絡請求場景時顯得力不從心。相比之下,cURL 雖然參數較多、學習曲線稍陡,但功能強大得多,幾乎是 PHP 進行網絡通訊的「瑞士軍刀」。

核心差異總覽

特性file_get_contentscURL
支持協議HTTP/HTTPS/FTP (受限於 allow_url_fopen)HTTP/HTTPS/FTP/FTPS/GOPHER/TELNET/DICT/FILE/LDAP 等
請求控制極難精細控制 Header、Cookie、Referer 等完整支持自定義 Header、Cookie 管理、Referer 偽裝
認證機制基礎 HTTP 認證Basic/Digest/NTLM/OAuth 等多種認證
代理支持不支持HTTP/SOCKS4/SOCKS5 代理,含認證
斷點續傳不支持原生支持 Range 請求與斷點續傳
並發請求串行阻塞支持 curl_multi 並發非阻塞
SSL/TLS 控制極其有限證書驗證、客戶端證書、密鑰對、Cipher 套件全可控
重定向策略自動跟隨,不可控可自定義最大重定向次數、是否跟隨、Header 轉發策略
超時控制受 default_socket_timeout 影響連接超時、執行超時、DNS 緩存超時獨立可控
錯誤處理僅返回 false,錯誤資訊獲取困難curl_errno/curl_error 提供詳細錯誤碼與描述

cURL 實戰入門:從零到一

環境啟用

PHP 預設未啟用 cURL 擴展,需修改 php.ini:

; 去掉前面的分號
extension=php_curl.dll
; Windows 下可能還需將 libeay32.dll、ssleay32.dll 複製到系統路徑

修改後重啟 Apache/IIS 或 php-fpm 使其生效。

基礎請求範例

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

// 2. 設定目標 URL
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/data');

// 3. 核心選項:將回傳內容作為字串返回,而非直接輸出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// 4. 常用選項:設定 User-Agent、超時、SSL 驗證
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MyBot/1.0)');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);           // 執行超時 10 秒
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);     // 連接超時 5 秒
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 開發環境暫時關閉 SSL 驗證
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// 5. 執行請求
$response = curl_exec($ch);

// 6. 錯誤檢查
if ($response === false) {
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    error_log("cURL Error [$errno]: $error");
} else {
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    // 處理 $response...
}

// 7. 關閉句柄,釋放資源
curl_close($ch);
?>

高頻應用場景速查

模擬瀏覽器登錄(Cookie 管理)

// 啟用 Cookie 檔案持久化
$cookieFile = sys_get_temp_dir() . '/cookie_' . md5($url) . '.txt';
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);  // 寫入 Cookie
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // 讀取 Cookie
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);       // 自動跟隨重定向

發送 POST 請求(API 對接、表單提交)

$postData = ['username' => 'user', 'password' => 'pass'];
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
// 或發送 JSON
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
// 或上傳檔案 (PHP 5.5+ 使用 CURLFile)
curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => new CURLFile('/path/to/file')]);

斷點續傳下載大檔案

$fp = fopen('large_file.zip', 'ab'); // 追加模式
$fileSize = filesize('large_file.zip');
curl_setopt($ch, CURLOPT_RANGE, $fileSize . '-'); // 從斷點續傳
curl_setopt($ch, CURLOPT_FILE, $fp);              // 直接寫入檔案句柄
curl_exec($ch);
fclose($fp);

並發請求(批量採集、API 聚合)

$mh = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_multi_add_handle($mh, $ch);
    $handles[$i] = $ch;
}

$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh); // 等待活動
} while ($running > 0);

foreach ($handles as $i => $ch) {
    $results[$i] = curl_multi_getcontent($ch);
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);

效能與資源考量

cURL 以擴展形式運行,底層使用 libcurl 庫,相比用戶態流封裝的 file_get_contents,在長連接復用、DNS 緩存、SSL 會話復用等方面效能優勢明顯。對於高併發採集場景,建議搭配 curl_multi 或 Swoole 協程化 cURL 使用。

總結建議

  • 簡單 GET 靜態資源獲取:file_get_contents 足矣,代碼更乾淨。
  • 任何涉及:POST、Header 自定義、Cookie、認證、代理、SSL 控制、斷點續傳、並發、詳細錯誤診斷 的場景:請毫猶豫選用 cURL。
  • 現代 PHP 專案:推薦使用 GuzzleHttp、Symfony HttpClient 等封裝庫,它們底層基於 cURL,提供更優雅的 OO 介面與中介軟體機制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved