WordPress 图片的秘密:wp_get_attachment_image_src()
深度解析
大家好! 今天咱们来聊聊 WordPress 里一个挺重要的函数:wp_get_attachment_image_src()
。这函数看着名字挺长,但作用很简单,就是根据图片 ID 和尺寸,给你返回图片的 URL 和尺寸信息。
可以把它想象成一个图片快递员,你告诉它图片的编号和想要的包装大小,它就能把图片的地址和实际尺寸告诉你。是不是很方便?
那么,这个“快递员”是怎么工作的呢? 咱们一起扒一扒它的源码,看看它到底是怎么找到并处理图片的。
1. 函数概览
首先,我们来看看 wp_get_attachment_image_src()
的基本用法:
<?php
$attachment_id = 123; // 你的图片 ID
$size = 'thumbnail'; // 预定义的尺寸,比如 'thumbnail', 'medium', 'large', 'full',或者一个数组 [width, height]
$image_data = wp_get_attachment_image_src( $attachment_id, $size );
if ( $image_data ) {
$image_url = $image_data[0]; // 图片 URL
$image_width = $image_data[1]; // 图片宽度
$image_height = $image_data[2]; // 图片高度
$image_is_intermediate = $image_data[3]; // 是否是中间尺寸图片
} else {
echo '找不到图片!';
}
?>
这个例子展示了最常见的用法。 你提供图片 ID 和尺寸,函数返回一个数组,包含图片的 URL、宽度、高度以及一个布尔值,告诉你这个图片是不是 WordPress 生成的中间尺寸图片。
2. 源码剖析:一步一步揭秘
现在,咱们深入源码,看看 wp_get_attachment_image_src()
到底是怎么实现的。
function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) {
$image = false;
$attachment_id = (int) $attachment_id;
if ( ! is_int( $attachment_id ) || $attachment_id < 1 ) {
return false;
}
// 1. 获取图片的 metadata
$image_src = wp_get_attachment_metadata( $attachment_id );
// 如果 metadata 不存在,说明图片可能损坏或丢失
if ( empty( $image_src ) ) {
return false;
}
// 2. 处理尺寸参数
if ( true === $icon ) {
$file = wp_mime_type_icon( $attachment_id );
$path = str_replace( wp_basename( $file ), '', $file );
$width = $height = 36;
} else {
if ( is_array( $size ) && 2 === count( $size ) ) {
// 如果 $size 是一个数组,直接使用数组中的宽度和高度
$width = intval( $size[0] );
$height = intval( $size[1] );
} elseif ( is_string( $size ) ) {
// 如果 $size 是一个字符串,从 WordPress 的尺寸配置中查找
$intermediate_size = image_get_intermediate_size( $attachment_id, $size );
if ( $intermediate_size ) {
$width = $intermediate_size['width'];
$height = $intermediate_size['height'];
}
}
// 如果找不到对应的尺寸,返回 false
if ( empty( $width ) || empty( $height ) ) {
return false;
}
// 3. 根据尺寸查找图片文件
$file = wp_get_attachment_image_file( $attachment_id, $width, $height );
// 如果找不到对应的文件,返回 false
if ( empty( $file ) ) {
return false;
}
// 4. 获取图片的 URL
$url = wp_get_attachment_url( $attachment_id );
// 5. 检查是否是中间尺寸图片
$is_intermediate = ( empty( $image_src['original_image'] ) || ( (string) $width !== (string) $image_src['width'] ) || ( (string) $height !== (string) $image_src['height'] ) );
}
// 6. 构建返回结果
if ( ! empty( $url ) && ! empty( $width ) && ! empty( $height ) ) {
$image = array( $url, $width, $height, $is_intermediate );
}
return $image;
}
咱们把上面的代码拆解成几个关键步骤,详细分析:
第一步:参数验证和初始化
$image = false;
$attachment_id = (int) $attachment_id;
if ( ! is_int( $attachment_id ) || $attachment_id < 1 ) {
return false;
}
- 首先,函数初始化
$image
为false
,这是默认的返回值,表示没有找到合适的图片。 - 然后,将传入的
$attachment_id
强制转换为整数,确保参数类型正确。 - 接着,进行参数验证,确保
$attachment_id
是一个有效的正整数。如果不是,直接返回false
。
第二步:获取图片的 Metadata
$image_src = wp_get_attachment_metadata( $attachment_id );
if ( empty( $image_src ) ) {
return false;
}
wp_get_attachment_metadata()
函数是关键,它负责从数据库中获取图片的元数据(metadata)。元数据包含了图片的各种信息,比如文件路径、尺寸、EXIF 信息等等。- 如果获取到的
$image_src
为空,说明该图片可能损坏或丢失,函数直接返回false
。
第三步:处理尺寸参数
这部分代码比较复杂,因为它需要处理各种不同的 $size
参数:
-
$icon = true
: 如果$icon
参数为true
,说明要获取的是附件的图标。 这时,函数会调用wp_mime_type_icon()
获取图标的文件路径,并设置宽度和高度为 36。if ( true === $icon ) { $file = wp_mime_type_icon( $attachment_id ); $path = str_replace( wp_basename( $file ), '', $file ); $width = $height = 36; }
-
$size
是数组: 如果$size
是一个包含两个元素的数组,比如[100, 200]
,那么数组的第一个元素就是宽度,第二个元素就是高度。if ( is_array( $size ) && 2 === count( $size ) ) { $width = intval( $size[0] ); $height = intval( $size[1] ); }
-
$size
是字符串: 如果$size
是一个字符串,比如'thumbnail'
或'medium'
,那么函数会调用image_get_intermediate_size()
来查找对应的宽度和高度。image_get_intermediate_size()
会从 WordPress 的设置中查找预定义的尺寸信息。elseif ( is_string( $size ) ) { $intermediate_size = image_get_intermediate_size( $attachment_id, $size ); if ( $intermediate_size ) { $width = $intermediate_size['width']; $height = $intermediate_size['height']; } }
-
尺寸校验: 如果经过上述处理,仍然没有获取到宽度和高度,说明传入的
$size
参数无效,函数返回false
。if ( empty( $width ) || empty( $height ) ) { return false; }
第四步:查找图片文件
$file = wp_get_attachment_image_file( $attachment_id, $width, $height );
if ( empty( $file ) ) {
return false;
}
wp_get_attachment_image_file()
函数负责根据图片 ID、宽度和高度,找到对应的图片文件。 这个函数会考虑 WordPress 生成的各种中间尺寸图片,并尝试找到最匹配的文件。- 如果找不到对应的文件,函数返回
false
。
第五步:获取图片的 URL
$url = wp_get_attachment_url( $attachment_id );
wp_get_attachment_url()
函数负责获取图片的 URL。 这个函数会根据 WordPress 的配置,返回图片的完整 URL。
第六步:检查是否是中间尺寸图片
$is_intermediate = ( empty( $image_src['original_image'] ) || ( (string) $width !== (string) $image_src['width'] ) || ( (string) $height !== (string) $image_src['height'] ) );
- 这部分代码用于判断返回的图片是否是 WordPress 生成的中间尺寸图片。
- 判断依据是:如果图片的元数据中没有
original_image
字段,或者返回的宽度和高度与原始图片的宽度和高度不一致,那么就认为是中间尺寸图片。
第七步:构建返回结果
if ( ! empty( $url ) && ! empty( $width ) && ! empty( $height ) ) {
$image = array( $url, $width, $height, $is_intermediate );
}
return $image;
- 最后,如果成功获取到了 URL、宽度和高度,函数会将这些信息封装到一个数组中,并返回。
-
数组的结构如下:
索引 含义 数据类型 0 图片 URL string 1 图片宽度 int 2 图片高度 int 3 是否是中间尺寸图片 bool
3. 辅助函数:幕后英雄
在 wp_get_attachment_image_src()
的实现中,有几个辅助函数起着关键作用:
wp_get_attachment_metadata()
: 负责从数据库中获取图片的元数据。image_get_intermediate_size()
: 负责根据尺寸名称(比如'thumbnail'
)查找对应的宽度和高度。wp_get_attachment_image_file()
: 负责根据图片 ID、宽度和高度,找到对应的图片文件。wp_get_attachment_url()
: 负责获取图片的 URL。
这些函数各司其职,共同完成了图片信息的查找和处理。
4. 尺寸的秘密:image_get_intermediate_size()
image_get_intermediate_size()
函数是处理尺寸参数的关键。 让我们看看它的源码:
function image_get_intermediate_size( $attachment_id, $size = 'thumbnail', $calc = true ) {
global $_wp_additional_image_sizes;
$imagedata = wp_get_attachment_metadata( $attachment_id );
if ( ! $imagedata ) {
return false;
}
if ( is_array( $size ) ) {
return false;
}
// Look for registered sizes first.
if ( isset( $_wp_additional_image_sizes[ $size ]['width'] ) && isset( $_wp_additional_image_sizes[ $size ]['height'] ) ) {
$width = intval( $_wp_additional_image_sizes[ $size ]['width'] );
$height = intval( $_wp_additional_image_sizes[ $size ]['height'] );
$crop = $_wp_additional_image_sizes[ $size ]['crop'];
} else {
// Standard sizes.
if ( 'thumbnail' == $size ) {
$width = intval( get_option( 'thumbnail_size_w' ) );
$height = intval( get_option( 'thumbnail_size_h' ) );
$crop = (bool) get_option( 'thumbnail_crop' );
} elseif ( 'medium' == $size ) {
$width = intval( get_option( 'medium_size_w' ) );
$height = intval( get_option( 'medium_size_h' ) );
$crop = false;
} elseif ( 'medium_large' == $size ) {
$width = intval( get_option( 'medium_large_size_w' ) );
$height = intval( get_option( 'medium_large_size_h' ) );
$crop = false;
} elseif ( 'large' == $size ) {
$width = intval( get_option( 'large_size_w' ) );
$height = intval( get_option( 'large_size_h' ) );
$crop = false;
} else {
return false;
}
}
if ( $calc ) {
$file = wp_get_attachment_image_file( $attachment_id, $width, $height );
if ( ! $file ) {
return false;
}
}
return array(
'width' => intval( $width ),
'height' => intval( $height ),
'crop' => $crop,
);
}
这个函数首先检查 $size
是否是一个已经注册的尺寸。 WordPress 允许主题和插件注册自定义的图片尺寸,这些尺寸信息存储在全局变量 $_wp_additional_image_sizes
中。
如果 $size
不是一个已注册的尺寸,函数会检查它是否是 WordPress 预定义的尺寸,比如 'thumbnail'
、'medium'
、'large'
等。 这些尺寸的宽度和高度存储在 WordPress 的选项中,函数会从选项中读取这些值。
如果 $size
既不是已注册的尺寸,也不是预定义的尺寸,函数会返回 false
。
5. 文件查找的艺术:wp_get_attachment_image_file()
wp_get_attachment_image_file()
函数负责根据图片 ID、宽度和高度,找到对应的图片文件。 这部分逻辑比较复杂,因为它需要考虑各种情况:
- 原始图片: 首先,函数会尝试找到原始图片,如果原始图片的宽度和高度与传入的宽度和高度一致,那么就返回原始图片。
- 中间尺寸图片: 如果找不到原始图片,函数会尝试找到最接近传入宽度和高度的中间尺寸图片。 WordPress 会根据配置生成各种中间尺寸的图片,函数会遍历这些图片,找到最匹配的一个。
- 缩放: 如果找不到完全匹配的图片,函数可能会对原始图片进行缩放,生成一个新的图片文件。
由于这部分代码比较复杂,就不在这里贴出完整的源码了。 但是,理解了 wp_get_attachment_image_file()
的基本原理,就能更好地理解 wp_get_attachment_image_src()
的工作方式。
6. 缓存的奥秘
为了提高性能,wp_get_attachment_image_src()
函数使用了缓存。 具体来说,函数会将图片的信息缓存到内存中,下次再请求相同的图片时,可以直接从缓存中读取,而不需要再次查询数据库和查找文件。
WordPress 使用对象缓存 API 来实现缓存。 对象缓存 API 允许插件和主题将数据存储到内存中,以便快速访问。
7. 总结
wp_get_attachment_image_src()
函数是 WordPress 中一个非常重要的函数,它负责根据图片 ID 和尺寸,获取图片的 URL 和尺寸信息。
咱们来总结一下:
- 参数验证和初始化: 确保传入的参数有效。
- 获取 Metadata: 从数据库中获取图片的元数据。
- 处理尺寸参数: 处理不同的
$size
参数,获取宽度和高度。 - 查找图片文件: 根据图片 ID、宽度和高度,找到对应的图片文件。
- 获取 URL: 获取图片的 URL。
- 检查是否是中间尺寸图片: 判断返回的图片是否是中间尺寸图片。
- 构建返回结果: 将图片信息封装到一个数组中,并返回。
通过深入分析 wp_get_attachment_image_src()
的源码,我们可以更好地理解 WordPress 是如何处理图片的,以及如何根据不同的尺寸获取对应的图片信息。 这对于开发 WordPress 主题和插件来说,是非常有帮助的。
希望今天的讲解对大家有所帮助!下次再见!