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) 取得副檔名
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";
}
allow_url_fopen = On。stream_context_create(['http' => ['timeout' => 10]]) 設定。getimagesize 會下載整個檔案再解析頭部。大型 PSD/TIFF 會佔用大量記憶體/頻寬。建議先用 HEAD 請求檢查 Content-Length,超過閾值跳過。stream_context_create(['ssl' => ['verify_peer' => false]])。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;
}
media:size:{md5($url)}, TTL 1 天)。getimagesize 並寫入快取/資料庫。fopen($url, 'rb') + fread($fp, 8192) 讀取前 8KB,配合 getimagesizefromstring() (PHP 5.4+) 解析,避免下載整檔。$imagick->readImage($url); $imagick->getImageWidth(),功能更豐富但記憶體佔用大。getimagesize() 是 PHP 獲取媒體尺寸最輕量、零依賴的方案。掌握其支援格式、回傳結構、遠程讀取限制、SSRF 防護與快取策略,即可在上傳驗證、媒體索引、縮圖生成等場景高效應用。