各位观众老爷们,晚上好!我是今天的讲座主持人,咱们今儿个来聊聊WordPress里一个神秘又重要的小精灵——wp_generate_attachment_metadata()
。这货藏在WordPress的核心深处,专门负责给上传的图片附件生成各种元数据,包括不同尺寸的图片URL,还有它们的尺寸信息。 听起来是不是有点枯燥?别担心,咱们用最通俗易懂的方式,把这小精灵扒个精光,看看它到底是怎么工作的。
一、背景故事:图片背后的秘密
话说,咱们往WordPress上传一张图片,表面上看只是多了个文件而已。但实际上,为了适应各种设备和布局,WordPress会在后台偷偷摸摸地生成一堆不同尺寸的副本。 比如,你上传了一张1920×1080的大图,WordPress可能会自动生成300×200的缩略图,600×400的中等尺寸图,还有1024×768的大尺寸图。 这些图可不是白生成的,它们的存在让你的网站在手机、平板、电脑上都能有最佳的显示效果。而wp_generate_attachment_metadata()
就是负责生成这些不同尺寸图片信息并记录下来的关键人物。
二、wp_generate_attachment_metadata()
:闪亮登场!
这个函数位于wp-includes/media.php
文件中。它的主要作用是:
- 生成缩略图和各种尺寸的图片。(如果需要)
- 获取图片的基本信息,如宽度、高度、文件大小等。
- 将这些信息整理成数组,并存储到
wp_postmeta
表中。
咱们先来看看它的函数原型:
function wp_generate_attachment_metadata( $attachment_id, $file ) {
// ...各种神秘代码...
return $metadata;
}
$attachment_id
:附件的ID,也就是wp_posts
表中对应的ID。$file
:附件的完整路径,例如/path/to/your/wp-content/uploads/2023/10/image.jpg
。- 返回值:一个包含附件元数据的数组。
三、代码剖析:一步一步揭秘
接下来,咱们一点一点地剖析wp_generate_attachment_metadata()
的源码,看看它是如何工作的。
-
准备工作:检查和设置
$attachment_id = (int) $attachment_id; $file = wp_normalize_path( $file ); // Check the file exists. if ( ! file_exists( $file ) ) { return false; } $metadata = array();
首先,函数会将
$attachment_id
转换为整数,并使用wp_normalize_path()
标准化文件路径。然后,它会检查文件是否存在。如果文件不存在,直接返回false
。最后,初始化一个空数组$metadata
,用于存储生成的元数据。 -
获取图片信息:让EXIF说话
$imagesize = getimagesize( $file ); $mime_type = false; if ( is_array( $imagesize ) ) { $mime_type = $imagesize['mime']; } if ( ! $mime_type ) { return false; } $metadata['width'] = $imagesize[0]; $metadata['height'] = $imagesize[1]; list( $uwidth, $uheight ) = wp_constrain_dimensions( $metadata['width'], $metadata['height'], 128, 96 ); $metadata['hwstring_small'] = "height='$uheight' width='$uwidth'"; $metadata['file'] = wp_basename( $file );
这里,
getimagesize()
函数闪亮登场,它可以获取图片的一些基本信息,比如宽度、高度、MIME类型等。如果getimagesize()
返回的是一个数组,说明获取信息成功。然后,将宽度和高度存储到$metadata
数组中。wp_constrain_dimensions()
函数用于限制图片的最大尺寸,这里限制为128×96,用于生成hwstring_small
属性,方便前端显示。最后,使用wp_basename()
获取文件名,并存储到$metadata['file']
中。 -
生成不同尺寸的图片:裁剪大师
$sizes = array(); foreach ( _wp_get_additional_image_sizes() as $size => $size_data ) { $sizes[ $size ] = array( 'width' => $size_data['width'], 'height' => $size_data['height'], 'crop' => $size_data['crop'], ); } $intermediate_size = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $attachment_id ); if ( apply_filters( 'image_resize_dimensions', true, $imagesize[0], $imagesize[1], $intermediate_size ) ) { $resized = image_make_intermediate_size( $file, $intermediate_size['width'], $intermediate_size['height'], $intermediate_size['crop'] ); if ( $resized ) { $metadata['sizes'][ $size ] = $resized; } }
这段代码是生成不同尺寸图片的关键。首先,它通过
_wp_get_additional_image_sizes()
函数获取所有已注册的图片尺寸。这些尺寸通常在主题的functions.php
文件中使用add_image_size()
函数注册。然后,它会遍历这些尺寸,并使用
image_make_intermediate_size()
函数生成对应尺寸的图片。image_make_intermediate_size()
函数会根据指定的宽度、高度和裁剪选项,生成一个新的图片文件,并返回该文件的相关信息,例如文件名、宽度、高度等。apply_filters( 'intermediate_image_sizes_advanced', $sizes, $attachment_id )
这个钩子允许开发者修改需要生成的图片尺寸。开发者可以通过这个钩子添加自定义的尺寸,或者删除不需要的尺寸。apply_filters( 'image_resize_dimensions', true, $imagesize[0], $imagesize[1], $intermediate_size )
这个钩子允许开发者自定义图片缩放的逻辑。让我们深入看一下
image_make_intermediate_size()
函数:function image_make_intermediate_size( $file, $width, $height, $crop = false ) { $resized_file = image_resize( $file, $width, $height, $crop ); if ( is_wp_error( $resized_file ) ) { return false; } $info = getimagesize( $resized_file ); $resized = array( 'file' => wp_basename( $resized_file ), 'width' => $info[0], 'height' => $info[1], ); return $resized; }
这个函数调用了
image_resize()
函数来实际执行图片的缩放和裁剪操作。image_resize()
是一个更底层的函数,它会根据 PHP 的 GD 库或 ImageMagick 库来完成图片的缩放和裁剪。 如果image_resize()
失败,则返回一个 WP_Error 对象,image_make_intermediate_size()
会返回 false。 否则,它会获取缩放后的图片的尺寸信息,并返回一个包含文件名、宽度和高度的数组。 -
生成缩略图:特殊待遇
$thumb_file = wp_get_attachment_thumb_file( $attachment_id ); if ( ! empty( $thumb_file ) && file_exists( $thumb_file ) ) { $thumb = getimagesize( $thumb_file ); if ( $thumb ) { $metadata['thumb'] = wp_basename( $thumb_file ); } }
这段代码专门处理缩略图。它首先使用
wp_get_attachment_thumb_file()
函数获取缩略图的文件路径。如果缩略图文件存在,则获取其尺寸信息,并将文件名存储到$metadata['thumb']
中。 -
生成 EXIF 元数据
// fetch additional metadata from exif/iptc. $image_meta = wp_read_image_metadata( $file ); if ( $image_meta ) { $metadata['image_meta'] = $image_meta; }
此代码段使用
wp_read_image_metadata()
函数从图像文件中提取EXIF和IPTC元数据。这些数据可以包含相机型号、拍摄日期、地理位置等信息。如果成功提取到元数据,则将其存储在$metadata['image_meta']
中。 -
优化图片(可选):更小的体积
/** This filter is documented in wp-includes/media.php */ $metadata = apply_filters( 'wp_generate_attachment_metadata', $metadata, $attachment_id, $file ); wp_maybe_rotate_exif( $file, $attachment_id, $metadata ); return $metadata;
在生成元数据之后,
wp_generate_attachment_metadata
函数会应用wp_generate_attachment_metadata
过滤器。 开发者可以使用此过滤器来修改元数据,例如添加自定义字段,或者执行一些额外的处理操作。wp_maybe_rotate_exif( $file, $attachment_id, $metadata );
函数会根据 EXIF 信息自动旋转图片。 某些相机在拍摄照片时会记录照片的方向信息,但默认情况下,WordPress 不会自动旋转照片。 这个函数会读取 EXIF 信息,如果发现照片需要旋转,则会自动旋转照片。 -
大结局:存储元数据
上面已经生成了所有需要的元数据,现在需要将这些数据存储到数据库中。 这通常是通过
wp_update_attachment_metadata()
函数来完成的,但这个函数并不在wp_generate_attachment_metadata()
函数内部调用。wp_generate_attachment_metadata()
函数只负责生成元数据,而wp_update_attachment_metadata()
函数负责将元数据存储到数据库中。wp_update_attachment_metadata()
函数的实现非常简单:function wp_update_attachment_metadata( $post_id, $metadata ) { return update_post_meta( $post_id, '_wp_attachment_metadata', $metadata ); }
它只是简单地调用
update_post_meta()
函数,将元数据存储到_wp_attachment_metadata
这个自定义字段中。
四、元数据结构:一览众山小
那么,wp_generate_attachment_metadata()
函数最终返回的$metadata
数组到底长什么样呢? 咱们来看一个示例:
Array
(
[width] => 1920
[height] => 1080
[file] => image.jpg
[sizes] => Array
(
[thumbnail] => Array
(
[file] => image-150x150.jpg
[width] => 150
[height] => 150
[mime-type] => image/jpeg
)
[medium] => Array
(
[file] => image-300x169.jpg
[width] => 300
[height] => 169
[mime-type] => image/jpeg
)
[large] => Array
(
[file] => image-1024x576.jpg
[width] => 1024
[height] => 576
[mime-type] => image/jpeg
)
[medium_large] => Array
(
[file] => image-768x432.jpg
[width] => 768
[height] => 432
[mime-type] => image/jpeg
)
[1536x1536] => Array
(
[file] => image-1536x864.jpg
[width] => 1536
[height] => 864
[mime-type] => image/jpeg
)
[2048x2048] => Array
(
[file] => image-1920x1080.jpg
[width] => 1920
[height] => 1080
[mime-type] => image/jpeg
)
)
[image_meta] => Array
(
[aperture] => 2.2
[credit] =>
[camera] => iPhone 7
=>
[created_timestamp] => 1509484800
[copyright] =>
[focal_length] => 2.8
[iso] => 20
[shutter_speed] => 0.0076923076923077
[title] =>
[orientation] => 1
[keywords] => Array
(
)
)
)
咱们来解读一下:
width
:原始图片的宽度。height
:原始图片的高度。file
:原始图片的文件名。sizes
:一个数组,包含了所有生成的图片尺寸的信息。每个尺寸都有file
(文件名)、width
(宽度)、height
(高度)和mime-type
(MIME类型)等属性。image_meta
:一个数组,包含了图片的EXIF元数据,例如相机型号、拍摄日期、光圈、ISO等。
五、钩子(Filters):扩展的翅膀
wp_generate_attachment_metadata()
函数提供了几个重要的钩子,允许开发者自定义其行为。
钩子名称 | 作用 | 参数 |
---|---|---|
intermediate_image_sizes_advanced |
修改需要生成的图片尺寸。开发者可以通过这个钩子添加自定义的尺寸,或者删除不需要的尺寸。 | $sizes (array): 默认的尺寸数组, $attachment_id (int): 附件ID |
image_resize_dimensions |
自定义图片缩放的逻辑。 | true (bool): 是否允许缩放, $orig_w (int): 原始宽度, $orig_h (int): 原始高度, $dest_w (int): 目标宽度, $dest_h (int): 目标高度, $crop (bool): 是否裁剪 |
wp_generate_attachment_metadata |
修改最终生成的元数据。 | $metadata (array): 元数据数组, $attachment_id (int): 附件ID, $file (string): 文件路径 |
六、总结:小精灵的强大力量
wp_generate_attachment_metadata()
函数虽然看起来不起眼,但它却是WordPress图片处理的核心。它负责生成不同尺寸的图片,并记录这些图片的信息,使得WordPress能够灵活地适应各种设备和布局。 通过理解wp_generate_attachment_metadata()
函数的源码,咱们可以更好地控制WordPress的图片处理流程,并根据自己的需求进行定制。
好了,今天的讲座就到这里。希望大家对wp_generate_attachment_metadata()
这个小精灵有了更深入的了解。 感谢大家的观看,咱们下期再见!