傳統做法 strlen(file_get_contents($url)) 需下載完整圖片,大檔案耗時耗頻寬。HTTP HEAD 請求僅取回標頭,Content-Length 即為檔案大小,極大提升效率。
<?php
function getRemoteFileSize($url, $timeout = 10) {
$parts = parse_url($url);
if (!$parts || !isset($parts['host'])) return false;
$host = $parts['host'];
$port = isset($parts['port']) ? $parts['port'] : 80;
$path = isset($parts['path']) ? $parts['path'] : '/';
if (isset($parts['query'])) $path .= '?' . $parts['query'];
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$fp) return false;
// 發送 HEAD 請求
$request = "HEAD $path HTTP/1.1\r\n";
$request .= "Host: $host\r\n";
$request .= "Connection: Close\r\n\r\n";
fwrite($fp, $request);
// 解析回應標頭
while (!feof($fp)) {
$header = fgets($fp);
if (stripos($header, 'Content-Length:') === 0) {
fclose($fp);
return (int)trim(substr($header, 15));
}
if (trim($header) === '') break; // 標頭結束
}
fclose($fp);
return false;
}
// 使用範例
$size = getRemoteFileSize('https://www.example.com/image.png');
if ($size !== false) {
echo "檔案大小: " . number_format($size) . " bytes (" . round($size/1024, 2) . " KB)";
} else {
echo "無法取得大小";
}
?>
$headers = get_headers($url, 1);
if (isset($headers['Content-Length'])) {
echo $headers['Content-Length'];
}
注意:get_headers()預設發送GET請求(部分伺服器會回傳內容),且會跟隨重導向。若需嚴格HEAD,仍建議用fsockopen或cURL。
function getFileSizeCurl($url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_NOBODY => true, // HEAD 請求
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false, // 測試用,生產請驗證憑證
CURLOPT_TIMEOUT => 10,
]);
curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
return $size > 0 ? (int)$size : false;
}
HEAD 或不回傳 Content-Length(如動態生成圖片、啟用壓縮傳輸),此時只能退回 GET 或 getimagesize()(會下載)。openssl 擴展。