使用 file_get_contents($url) 取遠端頁面,中文顯示亂碼。Firebug 觀察回應 Header 發現:Content-Encoding: gzip,伺服器開啟 GZIP 壓縮,file_get_contents 不會自動解壓,直接回傳二進位壓縮資料導致亂碼。
function curl_get($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => 'gzip', // 關鍵:自動接受並解壓 gzip/deflate
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; PHP Bot)',
CURLOPT_TIMEOUT => 10,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false, // 僅測試用,生產請驗證憑證
]);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$html = curl_get('https://example.com/page.html');
前提:PHP 編譯時啟用 --with-zlib(預設開啟)。
$html = file_get_contents('compress.zlib://' . $url);
原理:PHP 內建 compress.zlib:// 串流過濾器,讀取時自動解壓。
抓取後若仍亂碼,可能是來源頁面非 UTF-8(如 Big5、GB2312)。統一轉碼:
$encoding = mb_detect_encoding($html, ['UTF-8', 'GB2312', 'BIG5', 'CP950'], true);
if ($encoding && $encoding !== 'UTF-8') {
$html = mb_convert_encoding($html, 'UTF-8', $encoding);
}
function fetch_page($url) {
$html = @file_get_contents('compress.zlib://' . $url);
if ($html === false || strlen($html) < 100) { // 失敗或內容過短,嘗試 cURL
$html = curl_get($url);
}
// 編碼修正
$enc = mb_detect_encoding($html, ['UTF-8','GB2312','BIG5','CP950'], true);
if ($enc && $enc !== 'UTF-8') $html = mb_convert_encoding($html, 'UTF-8', $enc);
// 移除 BOM
if (substr($html, 0, 3) === "\xEF\xBB\xBF") $html = substr($html, 3);
return $html;
}
| 方法 | 支援 GZIP | 支援 HTTPS | 依賴擴展 | 速度 |
|---|---|---|---|---|
| file_get_contents | 否(需 zlib://) | 是 | 無 | 快 |
| file_get_contents + zlib:// | 是 | 是 | zlib | 快 |
| cURL | 是(CURLOPT_ENCODING) | 是 | curl | 中等 |
建議:優先 compress.zlib:// 簡潔高效,失敗 fallback cURL,並統一編碼轉 UTF-8。