PHP 提供多種讀取本地檔案與遠端資源的方式,各有適用場景、效能特性與限制。本文系統整理六種主流方法,附完整代碼範例與選擇指南。
<?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、大檔案一次載入記憶體。<?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 限制。<?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 等。<?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 環境。<?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;
}
?>
<?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;
?>
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);
}
?>
file_get_contentscURL(首選)或 stream_contextfopen + fread 迴圈fsockopencURL(唯一完整支援)fsockopen 或 cURL + CURLOPT_RESOLVE| 選項 | 用途 |
|---|---|
| CURLOPT_RETURNTRANSFER | 回傳字串而非直接輸出 |
| CURLOPT_CONNECTTIMEOUT | 連線逾時(秒) |
| CURLOPT_TIMEOUT | 總執行逾時(秒) |
| CURLOPT_FOLLOWLOCATION | 自動追蹤 3xx 重導向 |
| CURLOPT_MAXREDIRS | 最大重導向次數 |
| CURLOPT_COOKIEJAR / COOKIEFILE | Cookie 持久化檔案 |
| CURLOPT_SSL_VERIFYPEER | 驗證 SSL 憑證(生產建議 true) |
| CURLOPT_PROXY / CURLOPT_PROXYPORT | HTTP/HTTPS/SOCKS5 Proxy |
| CURLOPT_RESOLVE | 指定域名解析 IP(繞過 DNS) |
| CURLOPT_HTTPHEADER | 自訂請求標頭陣列 |
參考本系列其他文章:偽造 User-Agent、下載圖片偽造 Referer、cURL 多執行緒下載。