利用 fsockopen() 建立 TCP 連線至目標主機 80 埠,發送 HTTP/1.1 HEAD 或 GET 請求,解析回應標頭中的 Content-Length 即可得知檔案大小,無需下載完整內容。
<?php
function getRemoteFileSize($url) {
$parsed = parse_url($url);
if (!$parsed || !isset($parsed['host'])) {
return false;
}
$host = $parsed['host'];
$path = isset($parsed['path']) ? $parsed['path'] : '/';
if (isset($parsed['query'])) {
$path .= '?' . $parsed['query'];
}
$port = isset($parsed['port']) ? $parsed['port'] : 80;
$fp = @fsockopen($host, $port, $errno, $errstr, 10);
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);
$headers = '';
while (!feof($fp)) {
$line = fgets($fp, 1024);
$headers .= $line;
if ($line === "\r\n") break; // 標頭結束
}
fclose($fp);
// 解析 Content-Length
if (preg_match('/Content-Length:\s*(\d+)/i', $headers, $matches)) {
return (int)$matches[1];
}
return false;
}
// 測試
$url = 'https://www.example.com/largefile.zip';
$size = getRemoteFileSize($url);
if ($size !== false) {
echo "檔案大小: " . number_format($size) . " bytes (" . round($size/1024/1024, 2) . " MB)";
} else {
echo "無法取得檔案大小";
}
?>
/Content-Length:\s*(\d+)/i 不區分大小寫,兼容不同伺服器回應格式。false。fsockopen 改為 ssl:// 協定並連接 443 埠,或改用 stream_context_create 搭配 file_get_contents。Range 標頭實作下載進度條。