file_get_contents() 依賴 allow_url_fopen=On,且不支援 HTTPS 驗證、POST、Cookie、Header 自訂等進階功能。生產環境建議統一使用 cURL。
<?php
function fetchUrl($url, $options = []) {
$ch = curl_init($url);
curl_setopt_array($ch, array_merge([
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => true, // 生產環境建議 true
CURLOPT_FOLLOWLOCATION => true, // 自動跟隨 3xx
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; PHP Bot)',
], $options));
$content = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($errno) {
throw new Exception("cURL Error [$errno]: $error");
}
if ($info['http_code'] >= 400) {
throw new Exception("HTTP {$info['http_code']}: $url");
}
return $content;
}
// 使用範例
try {
$html = fetchUrl('https://www.example.com/');
echo $html;
} catch (Exception $e) {
echo '抓取失敗: ' . $e->getMessage();
}
?>
| 原因 | 說明 | 解決 |
|---|---|---|
| allow_url_fopen=Off | php.ini 關閉遠端開啟 | 改用 cURL 或開啟設定(不建議) |
| HTTPS 憑證驗證失敗 | 無 CA 憑證或自簽憑證 | cURL 設定 CURLOPT_CAINFO 或暫時關閉驗證 |
| 目標網站封鎖 PHP User-Agent | 預設 User-Agent 為 "PHP/版本" | cURL 自訂 CURLOPT_USERAGENT |
| 需求 POST / Cookie / Header | file_get_contents 僅支援 GET | cURL 完整支援 |
| 連線逾時無法控制 | 受 default_socket_timeout 限制 | cURL 可精確設定連線/讀取逾時 |
<?php
$url = 'https://api.example.com/protected';
$options = [
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => 'username:password',
];
$content = fetchUrl($url, $options);
?>
封裝成可重用的 HttpClient 類別,統一處理錯誤、重試、日誌、快取,是現代 PHP 專案的標準做法。