wp_get_image_mime()
云策文档标注
概述
wp_get_image_mime() 函数用于返回图像文件的真实 MIME 类型,依赖于 exif_imagetype() 或 getimagesize() 进行检测,并包含对 WebP、AVIF 和 HEIC 等格式的降级支持。
关键要点
- 函数接受一个必需参数 $file,表示文件的完整路径。
- 返回值为字符串(MIME 类型)或 false(如果无法确定类型)。
- 优先使用 exif_imagetype(),若不可用则回退到 getimagesize(),并处理调试模式下的错误抑制。
- 包含对 WebP、AVIF 和 HEIC 格式的降级检测逻辑,通过读取文件头信息实现。
- 在 WordPress 6.7.0 中增加了对 HEIC 图像的支持,6.5.0 支持 AVIF,5.8.0 支持 WebP,最初在 4.7.1 版本引入。
代码示例
function wp_get_image_mime( $file ) {
try {
if ( is_callable( 'exif_imagetype' ) ) {
$imagetype = exif_imagetype( $file );
$mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
} elseif ( function_exists( 'getimagesize' ) ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! defined( 'WP_RUN_CORE_TESTS' ) ) {
$imagesize = getimagesize( $file );
} else {
$imagesize = @getimagesize( $file );
}
$mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
} else {
$mime = false;
}
if ( false !== $mime ) {
return $mime;
}
$magic = file_get_contents( $file, false, null, 0, 12 );
if ( false === $magic ) {
return false;
}
$magic = bin2hex( $magic );
if ( ( str_starts_with( $magic, '52494646' ) ) && ( 16 === strpos( $magic, '57454250' ) ) ) {
$mime = 'image/webp';
}
$magic = str_split( $magic, 8 );
if ( isset( $magic[1] ) && isset( $magic[2] ) && 'ftyp' === hex2bin( $magic[1] ) ) {
if ( 'avif' === hex2bin( $magic[2] ) || 'avis' === hex2bin( $magic[2] ) ) {
$mime = 'image/avif';
} elseif ( 'heic' === hex2bin( $magic[2] ) ) {
$mime = 'image/heic';
} elseif ( 'heif' === hex2bin( $magic[2] ) ) {
$mime = 'image/heif';
} else {
if ( extension_loaded( 'fileinfo' ) ) {
$fileinfo = finfo_open( FILEINFO_MIME_TYPE );
$mime_type = finfo_file( $fileinfo, $file );
}
}
}
return $mime;
} catch ( Exception $e ) {
return false;
}
}注意事项
- 函数在检测失败时会尝试通过文件头进行降级检测,支持 WebP、AVIF 和 HEIC 格式。
- 在调试模式下(WP_DEBUG 为 true),getimagesize() 的错误不会被抑制,除非运行核心测试。
- 函数可能返回 false,表示无法确定 MIME 类型,调用者应处理此情况。
原文内容
Returns the real mime type of an image file.
Description
This depends on exif_imagetype() or getimagesize() to determine real mime types.
Parameters
$filestringrequired-
Full path to the file.
Source
function wp_get_image_mime( $file ) {
/*
* Use exif_imagetype() to check the mimetype if available or fall back to
* getimagesize() if exif isn't available. If either function throws an Exception
* we assume the file could not be validated.
*/
try {
if ( is_callable( 'exif_imagetype' ) ) {
$imagetype = exif_imagetype( $file );
$mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
} elseif ( function_exists( 'getimagesize' ) ) {
// Don't silence errors when in debug mode, unless running unit tests.
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! defined( 'WP_RUN_CORE_TESTS' ) ) {
// Not using wp_getimagesize() here to avoid an infinite loop.
$imagesize = getimagesize( $file );
} else {
$imagesize = @getimagesize( $file );
}
$mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
} else {
$mime = false;
}
if ( false !== $mime ) {
return $mime;
}
$magic = file_get_contents( $file, false, null, 0, 12 );
if ( false === $magic ) {
return false;
}
/*
* Add WebP fallback detection when image library doesn't support WebP.
* Note: detection values come from LibWebP, see
* https://github.com/webmproject/libwebp/blob/master/imageio/image_dec.c#L30
*/
$magic = bin2hex( $magic );
if (
// RIFF.
( str_starts_with( $magic, '52494646' ) ) &&
// WEBP.
( 16 === strpos( $magic, '57454250' ) )
) {
$mime = 'image/webp';
}
/**
* Add AVIF fallback detection when image library doesn't support AVIF.
*
* Detection based on section 4.3.1 File-type box definition of the ISO/IEC 14496-12
* specification and the AV1-AVIF spec, see https://aomediacodec.github.io/av1-avif/v1.1.0.html#brands.
*/
// Divide the header string into 4 byte groups.
$magic = str_split( $magic, 8 );
if ( isset( $magic[1] ) && isset( $magic[2] ) && 'ftyp' === hex2bin( $magic[1] ) ) {
if ( 'avif' === hex2bin( $magic[2] ) || 'avis' === hex2bin( $magic[2] ) ) {
$mime = 'image/avif';
} elseif ( 'heic' === hex2bin( $magic[2] ) ) {
$mime = 'image/heic';
} elseif ( 'heif' === hex2bin( $magic[2] ) ) {
$mime = 'image/heif';
} else {
/*
* HEIC/HEIF images and image sequences/animations may have other strings here
* like mif1, msf1, etc. For now fall back to using finfo_file() to detect these.
*/
if ( extension_loaded( 'fileinfo' ) ) {
$fileinfo = finfo_open( FILEINFO_MIME_TYPE );
$mime_type = finfo_file( $fileinfo, $file );
if ( PHP_VERSION_ID < 80100 ) { // finfo_close() has no effect as of PHP 8.1.
finfo_close( $fileinfo );
}
if ( wp_is_heic_image_mime_type( $mime_type ) ) {
$mime = $mime_type;
}
}
}
}
} catch ( Exception $e ) {
$mime = false;
}
return $mime;
}