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

PHP 使用 getimagesize() 獲取 Flash (SWF) 尺寸資訊:支援格式、URL 遠程讀取、MIME 類型判斷與安全過濾

     編輯:PHP 綜合知識

getimagesize() 是 PHP 內建函式,支援 GIF、JPG、PNG、SWF、PSD、TIFF、BMP、IFF、JP2、JPX、JB2、JPC、XBM、WBMP 等格式,可直接讀取本地或遠程 URL 的圖片/Flash 尺寸、類型、MIME,無需解析二進位頭部。本文詳細說明用法、回傳值結構、遠程讀取注意事項、安全過濾與效能優化。

基本用法

// 本地檔案
$info = getimagesize('/path/to/flash.swf');
print_r($info);

// 遠程 URL (PHP 4.0.5+ 支援)
$url = 'https://example.com/banner.swf';
$info = @getimagesize($url); // 加 @ 抑制警告,自行檢查回傳值
if ($info === false) {
    echo "無法讀取或非支援格式";
}

回傳值結構詳解

Array
(
    [0] => 540          // 寬度 (像素)
    [1] => 250          // 高度 (像素)
    [2] => 13           // 圖片類型常數 (IMAGETYPE_SWF = 13)
    [3] => width="540" height="250"  // 可直接用於  標籤的屬性字串
    [bits] => 8         // 色深 (位元/像素)
    [channels] => 3     // 通道數 (3=RGB, 4=RGBA)
    [mime] => application/x-shockwave-flash  // MIME 類型
)

圖片類型常數對照表

IMAGETYPE_GIF          = 1
IMAGETYPE_JPEG         = 2
IMAGETYPE_PNG          = 3
IMAGETYPE_SWF          = 13
IMAGETYPE_PSD          = 14
IMAGETYPE_BMP          = 16
IMAGETYPE_TIFF_II      = 17
IMAGETYPE_TIFF_MM      = 18
IMAGETYPE_JPC          = 19
IMAGETYPE_JP2          = 20
IMAGETYPE_JPX          = 21
IMAGETYPE_JB2          = 22
IMAGETYPE_SWC          = 23
IMAGETYPE_IFF          = 24
IMAGETYPE_WBMP         = 25
IMAGETYPE_XBM          = 26
// 使用 image_type_to_mime_type($type) 取得 MIME
// 使用 image_type_to_extension($type, false) 取得副檔名

實戰:批次掃描目錄獲取所有圖片/Flash 尺寸

function scanMediaDimensions(string $dir): Generator {
    $allowedTypes = [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_SWF, IMAGETYPE_WEBP];
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS));
    foreach ($iterator as $file) {
        if (!$file->isFile()) continue;
        $path = $file->getPathname();
        $info = @getimagesize($path);
        if ($info === false) continue;
        if (!in_array($info[2], $allowedTypes, true)) continue;
        yield [
            'path' => $path,
            'width' => $info[0],
            'height' => $info[1],
            'type' => image_type_to_mime_type($info[2]),
            'size' => $file->getSize(),
            'mtime' => $file->getMTime(),
        ];
    }
}

// 使用
foreach (scanMediaDimensions('/var/www/uploads') as $media) {
    echo "{$media['path']}: {$media['width']}x{$media['height']} ({$media['type']})\n";
}

遠程 URL 讀取注意事項

  1. allow_url_fopen:php.ini 必須開啟 allow_url_fopen = On。
  2. 超時控制:預設 60 秒,可用 stream_context_create(['http' => ['timeout' => 10]]) 設定。
  3. 大檔案:getimagesize 會下載整個檔案再解析頭部。大型 PSD/TIFF 會佔用大量記憶體/頻寬。建議先用 HEAD 請求檢查 Content-Length,超過閾值跳過。
  4. 重定向:自動跟隨 HTTP 3xx 重定向,但不支援 Meta Refresh/JS 跳轉。
  5. SSL 驗證:PHP 5.6+ 預設驗證憑證,自簽憑證需 stream_context_create(['ssl' => ['verify_peer' => false]])。

安全過濾:防止 SSRF 與惡意檔案

function safeGetImageSize(string $url): array|false {
    // 1. 協議白名單
    $parsed = parse_url($url);
    if (!in_array($parsed['scheme'] ?? '', ['http', 'https'], true)) return false;

    // 2. 域名/IP 解析檢查 (防 SSRF 訪問內網)
    $host = $parsed['host'] ?? '';
    $ips = @dns_get_record($host, DNS_A | DNS_AAAA);
    foreach ($ips as $ip) {
        $ipAddr = $ip['ip'] ?? ($ip['ipv6'] ?? '');
        if (filter_var($ipAddr, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
            return false; // 解析到私有/保留 IP,拒絕
        }
    }

    // 3. 建立受限流上下文
    $ctx = stream_context_create([
        'http' => [
            'timeout' => 5,
            'max_redirects' => 3,
            'header' => 'User-Agent: PHP-getimagesize/1.0',
        ],
        'ssl' => ['verify_peer' => true, 'verify_peer_name' => true],
    ]);

    // 4. 讀取並驗證
    $info = @getimagesize($url, $info, $ctx); // 第 3 參數為 imageinfo (輸出), 第 4 參數才是 context (PHP 7.1+)
    // 正確寫法:
    $info = @getimagesize($url);
    if ($info === false) return false;

    // 5. MIME 白名單
    $allowedMimes = ['image/gif', 'image/jpeg', 'image/png', 'image/webp', 'application/x-shockwave-flash'];
    if (!in_array($info['mime'] ?? '', $allowedMimes, true)) return false;

    return $info;
}

效能優化

  • 快取結果:尺寸資訊不常變更,存入 Redis (Key: media:size:{md5($url)}, TTL 1 天)。
  • 非同步預熱:上傳完成後推入佇列,Worker 執行 getimagesize 並寫入快取/資料庫。
  • 僅讀取頭部:大檔案可用 fopen($url, 'rb') + fread($fp, 8192) 讀取前 8KB,配合 getimagesizefromstring() (PHP 5.4+) 解析,避免下載整檔。

現代替代方案

  • getID3:功能強大的媒體檔案分析庫,支援更多格式、ID3 標籤、視訊編碼資訊。
  • FFprobe (FFmpeg):命令列工具,解析視訊/音訊/圖片完整中繼資料,適合影音平台。
  • ImageMagick (imagick 擴展):$imagick->readImage($url); $imagick->getImageWidth(),功能更豐富但記憶體佔用大。

getimagesize() 是 PHP 獲取媒體尺寸最輕量、零依賴的方案。掌握其支援格式、回傳結構、遠程讀取限制、SSRF 防護與快取策略,即可在上傳驗證、媒體索引、縮圖生成等場景高效應用。

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