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

PHP 讀取檔案/網頁內容六大方法完整比較:file_get_contents、fopen、cURL、fsockopen 等

     編輯:PHP 相關知識

PHP 提供多種讀取本地檔案與遠端資源的方式,各有適用場景、效能特性與限制。本文系統整理六種主流方法,附完整代碼範例與選擇指南。

方法一:file_get_contents(最簡單、推薦首選)

<?php
$url = 'https://www.example.com/';
$html = file_get_contents($url);
// $http_response_header 陣列自動填入回應標頭
echo $html;
?>
  • 優點:一行搞定、記憶體映射優化、支援 stream_context 進階控制。
  • 缺點:需 allow_url_fopen=On、無法精細控制 Timeout/重導向/Cookie/Proxy、大檔案一次載入記憶體。

方法二:fopen + fgets/fread(串流逐行/塊讀取)

<?php
$fp = fopen($url, 'r');
if ($fp) {
    stream_get_meta_data($fp); // 取得標頭等中繼資料
    while (!feof($fp)) {
        $result .= fgets($fp, 1024); // 或 fread($fp, 8192)
    }
    fclose($fp);
}
echo $result;
?>
  • 優點:可控制讀取緩衝區大小、適合大檔案、可中途中斷。
  • 缺點:程式碼較冗長、同樣受 allow_url_fopen 限制。

方法三:file_get_contents + stream_context(POST、自訂標頭、Timeout)

<?php
$data = http_build_query(array('foo' => 'bar'));
$opts = array(
    'http' => array(
        'method'  => 'POST',
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n" .
                     "Content-Length: " . strlen($data) . "\r\n",
        'content' => $data,
        'timeout' => 10, // 秒
    )
);
$context = stream_context_create($opts);
$html = file_get_contents('https://localhost/api', false, $context);
?>
  • 關鍵:stream_context_create 可設定 timeout、proxy、user_agent、follow_location 等。

方法四:fsockopen(原始 Socket,完整控制 HTTP 協定)

<?php
function get_url($url, $cookie = false) {
    $url_parts = parse_url($url);
    $query = $url_parts['path'] . ($url_parts['query'] ? '?' . $url_parts['query'] : '');
    $fp = fsockopen($url_parts['host'], $url_parts['port'] ?? 80, $errno, $errstr, 30);
    if (!$fp) return false;

    $request = "GET $query HTTP/1.1\r\n";
    $request .= "Host: {$url_parts['host']}\r\n";
    $request .= "Connection: Close\r\n";
    if ($cookie) $request .= "Cookie: $cookie\r\n";
    $request .= "\r\n";
    fwrite($fp, $request);

    $response = '';
    while (!feof($fp)) $response .= fgets($fp, 1024);
    fclose($fp);
    return $response; // 含標頭與主體
}

function get_url_html($url, $cookie = false) {
    $raw = get_url($url, $cookie);
    if ($raw) {
        $pos = strpos($raw, "\r\n\r\n");
        return $pos !== false ? substr($raw, $pos + 4) : $raw;
    }
    return false;
}
?>
  • 適用:需精細控制請求行、標頭、處理非標準回應、無 allow_url_fopen 環境。

方法五:fsockopen POST 版本

<?php
function http_post($url, $data, $cookie, $referrer = '') {
    $info = parse_url($url);
    $port = $info['port'] ?? 80;
    $post_data = http_build_query($data);

    $fp = fsockopen($info['host'], $port, $errno, $errstr, 30);
    if (!$fp) return false;

    $request = "POST {$info['path']} HTTP/1.1\r\n";
    $request .= "Host: {$info['host']}\r\n";
    $request .= "Referer: $referrer\r\n";
    $request .= "Content-type: application/x-www-form-urlencoded\r\n";
    $request .= "Content-length: " . strlen($post_data) . "\r\n";
    $request .= "Connection: close\r\n";
    $request .= "Cookie: $cookie\r\n\r\n";
    $request .= $post_data;

    fwrite($fp, $request);
    $response = '';
    while (!feof($fp)) $response .= fgets($fp, 1024);
    fclose($fp);
    return $response;
}
?>

方法六:cURL(功能最完整、效能最佳、生產首選)

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.example.com/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; PHP Bot)');
$file_contents = curl_exec($ch);
curl_close($ch);
echo $file_contents;
?>
  • 核心優勢:支援 HTTPS、Proxy、Cookie 罐、多執行緒、斷點續傳、進度回調、HTTP/2、Unix Socket 等。
  • 啟用:extension=curl(Windows 需解決 DLL 相依,見前文)。

七、通用封裝函數:自動偵測可用方式

<?php
function vita_get_url_content($url) {
    if (function_exists('file_get_contents') && ini_get('allow_url_fopen')) {
        return file_get_contents($url);
    }
    if (function_exists('curl_init')) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        $content = curl_exec($ch);
        curl_close($ch);
        return $content;
    }
    // 最後備援:fsockopen
    return get_url($url);
}
?>

八、選擇指南決策樹

  1. 簡單 GET、小檔案、允許 url_fopen → file_get_contents
  2. 需 POST/自訂標頭/Timeout/Proxy/Cookie → cURL(首選)或 stream_context
  3. 大檔案(>100MB)、串流處理、記憶體受限 → fopen + fread 迴圈
  4. 無 url_fopen、無 cURL、需完整 HTTP 控制 → fsockopen
  5. 防火牆/Proxy 環境、需 NTLM/Kerberos 認證 → cURL(唯一完整支援)
  6. 同域多 IP 負載均衡、需指定 IP 送 Host 標頭 → fsockopen 或 cURL + CURLOPT_RESOLVE

九、cURL 進階常用選項速查

選項用途
CURLOPT_RETURNTRANSFER回傳字串而非直接輸出
CURLOPT_CONNECTTIMEOUT連線逾時(秒)
CURLOPT_TIMEOUT總執行逾時(秒)
CURLOPT_FOLLOWLOCATION自動追蹤 3xx 重導向
CURLOPT_MAXREDIRS最大重導向次數
CURLOPT_COOKIEJAR / COOKIEFILECookie 持久化檔案
CURLOPT_SSL_VERIFYPEER驗證 SSL 憑證(生產建議 true)
CURLOPT_PROXY / CURLOPT_PROXYPORTHTTP/HTTPS/SOCKS5 Proxy
CURLOPT_RESOLVE指定域名解析 IP(繞過 DNS)
CURLOPT_HTTPHEADER自訂請求標頭陣列

十、遠端抓取實戰範例:抓取標題、儲存圖片、多執行緒下載

參考本系列其他文章:偽造 User-Agent、下載圖片偽造 Referer、cURL 多執行緒下載。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved