首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 獲取遠程圖片大小:CURL HEAD 請求解析 Content-Length

     編輯:PHP 相關知識

無需下載完整圖片,僅通過 HTTP HEAD 請求獲取響應頭中的 Content-Length 即可獲得文件大小。適用於圖片驗證、下載預判、存儲配額檢查等場景。

核心函數實現

 true,   // 輸出頭部
        CURLOPT_NOBODY         => true,   // HEAD 請求,不下載 Body
        CURLOPT_RETURNTRANSFER => true,   // 返回字符串而非直接輸出
        CURLOPT_FOLLOWLOCATION => true,   // 跟隨重定向
        CURLOPT_TIMEOUT        => 10,     // 超時秒數
        CURLOPT_SSL_VERIFYPEER => false,  // 可選:跳過 SSL 驗證 (生產建議開啟並配置 CA)
    ]);
    
    // 3. HTTP Basic Auth (可選)
    if ($user && $pw) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Basic ' . base64_encode("$user:$pw")
        ]);
    }
    
    // 4. 執行並捕獲頭部
    curl_exec($ch);
    curl_close($ch);
    $head = ob_get_contents();
    ob_end_clean();
    
    // 5. 正則提取 Content-Length
    if (preg_match('/Content-Length:\s*(\d+)/i', $head, $matches)) {
        $bytes = (int)$matches[1];
        $kb    = round($bytes / 1024, 3);
        $mb    = round($bytes / (1024 * 1024), 3);
        return "$kb KB / $mb MB";
    }
    return 'unknown';
}

// 使用示例
$url = "https://example.com/image.jpg";
echo remote_filesize($url); // 輸出: 45.231 KB / 0.044 MB

關鍵技術點

設置作用
CURLOPT_NOBODY => true發送 HEAD 請求,僅獲取頭部,節省帶寬/時間
CURLOPT_HEADER => true將響應頭包含在輸出中
CURLOPT_RETURNTRANSFER => true返回字符串,配合 ob_start() 捕獲
CURLOPT_FOLLOWLOCATION => true自動處理 301/302 重定向,獲取最終資源大小
正則 /Content-Length:\s*(\d+)/i不區分大小寫匹配,兼容頭部格式變化

進階增強版:支援 Chunked Transfer / 無 Content-Length 場景

function remote_filesize_advanced($uri) {
    $ch = curl_init($uri);
    curl_setopt_array($ch, [
        CURLOPT_NOBODY => true,
        CURLOPT_HEADER => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
    ]);
    $response = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
    
    // 1. 優先用 curl_getinfo 獲取 (更可靠)
    $size = $info['download_content_length']; // -1 表示未知
    if ($size > 0) {
        return format_size($size);
    }
    
    // 2. 回退解析頭部
    if (preg_match('/Content-Length:\s*(\d+)/i', $response, $m)) {
        return format_size((int)$m[1]);
    }
    
    // 3. Transfer-Encoding: chunked 無法獲取精確大小
    if (stripos($response, 'Transfer-Encoding: chunked') !== false) {
        return 'chunked (unknown size)';
    }
    return 'unknown';
}

function format_size($bytes) {
    $kb = round($bytes / 1024, 2);
    $mb = round($bytes / 1048576, 2);
    return "$kb KB / $mb MB";
}
  • curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD) (或 $info['download_content_length']) 直接獲取解析後的 Content-Length,**比正則更可靠**,自動處理重定向後的最終值。
  • Chunked 編碼響應無 Content-Length,無法預知大小,需實際下載累計才能得知。

應用場景與注意事項

  1. 圖片上傳預檢:用戶提交圖片 URL 時,先檢測大小是否超限,再決定是否下載存儲。
  2. 防盜鏈/防竊鏈檢測:某些防盜鏈返回 403/小圖片,Content-Length 異常可作為判斷依據。
  3. CDN/對象存儲:AWS S3、阿里云 OSS 等均標準支援 HEAD 請求返回 Content-Length。
  4. 緩存結果:同一 URL 短期內重複檢測,緩存大小結果 (Redis TTL 1小時)。
  5. SSL 驗證:生產環境**務必開啟** CURLOPT_SSL_VERIFYPEER => true 並配置 CURLOPT_CAINFO,防中間人攻擊。

總結

CURL HEAD 請求 + curl_getinfo() 獲取 Content-Length 是**獲取遠程文件大小的標準、高效、可靠方案**。避免 file_get_contents 下載全文件的帶寬浪費與內存壓力,配合緩存與 SSL 驗證,可構建健壯的遠程資源元信息檢測服務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved