在 PHP 開發中,經常需要獲取遠程文件的大小(例如下載前檢查、顯示文件信息)。本文介紹三種常用方法,並說明各自的優缺點與適用場景。
file_get_contents() 獲取內容長度<?php
$url = 'https://example.com/file.zip';
$content = file_get_contents($url);
echo strlen($content); // 輸出文件大小(字節)
?>
優點:代碼簡單直觀。
缺點:會將整個文件下載到內存,大文件極易導致內存耗盡或超時,不推薦用於大文件。
前提:需開啟 allow_url_fopen。
get_headers() 獲取 Content-Length 頭<?php
$url = 'https://example.com/file.zip';
$headers = get_headers($url, true);
$size = $headers['Content-Length'] ?? 0;
echo $size; // 輸出文件大小(字節)
?>
優點:只發送 HEAD 請求,不下載文件內容,速度快、內存佔用極低。
缺點:依賴服務器正確返回 Content-Length 頭;部分服務器(如動態生成內容、分塊傳輸)可能不返回該頭。
前提:需開啟 allow_url_fopen,否則會報錯 Warning: get_headers(): URL file-access is disabled。
fsockopen() 手動發送 HTTP 請求解析頭部<?php
function getRemoteFileSize($url) {
$parsed = parse_url($url);
if (empty($parsed['host'])) return false;
$host = $parsed['host'];
$port = $parsed['port'] ?? 80;
$path = $parsed['path'] ?? '/';
if (!empty($parsed['query'])) $path .= '?' . $parsed['query'];
$fp = fsockopen($host, $port, $errno, $errstr, 10);
if (!$fp) return false;
$request = "HEAD $path HTTP/1.1\r\nHost: $host\r\nConnection: Close\r\n\r\n";
fwrite($fp, $request);
$size = false;
while (!feof($fp)) {
$line = fgets($fp, 1024);
if (trim($line) === '') break; // 頭部結束
if (stripos($line, 'Content-Length:') === 0) {
$size = (int)trim(substr($line, 15));
break;
}
}
fclose($fp);
return $size;
}
// 使用示例
$url = 'https://example.com/file.zip';
$size = getRemoteFileSize($url);
echo $size ?: '無法獲取大小';
?>
優點:不依賴 allow_url_fopen,可在該選項關閉的環境下工作;可精確控制請求細節(如超時、User-Agent、HTTPS 需用 ssl:// 協議)。
缺點:代碼較複雜;需自行處理 HTTPS(使用 ssl://$host 並端口 443)、重定向、分塊傳輸等情況。
| 方法 | 適用場景 | 依賴配置 | 性能 |
|---|---|---|---|
| file_get_contents | 極小文件、簡單腳本 | allow_url_fopen=On | 差(下載全文件) |
| get_headers | 大多數靜態文件、CDN 資源 | allow_url_fopen=On | 優(僅 HEAD 請求) |
| fsockopen | 受限環境、需自定義請求、HTTPS | 無特殊要求 | 良(需自行實現健壯性) |
推薦策略:優先使用 get_headers();若 allow_url_fopen 關閉或需支持 HTTPS/重定向,則封裝基於 fsockopen(或更現代的 cURL)的健壯函數。