Wordpress中文章的特色图像Featured Image究竟存在哪里?

最近项目需要,分析了一下Wordpress的特色图像 Feature Image的上传、保存方式,这一分析觉得Wordpress的数据结构设计还真是有想法。

先简单说一下结论:

Wordpress中图像物理文件保存在 wp-content/uploads 目录下,相关信息保存在 wp_posts 表中。post_type 是 attachment,post-mime-type 是 image/png。通过 post_parent 与文章关联。

我原来以为图片信息会有单独的表存放,没想到都放在 wp_posts 中,于是分析了这样做有什么好处。

wp_posts 表

首先来看看 wp_posts 表。该表用来存放文章信息,如文章标题、正文、摘要、作者、发布时间、访问密码、评论数、修改时间、文章地址(非静态化之前的,带?和数字ID)等。这些属性都是与文章相关的,同时根据 post_type的不同,该表还能用来存储特色图像 Featured Image。

字段 含义
ID 自增唯一ID
post_author 对应作者ID
post_date 发布时间
post_date_gmt 发布时间(GMT+0时间)
post_content 正文
post_title 标题
post_excerpt 摘录
post_status 文章状态(publish
comment_status 评论状态(open
ping_status PING/Trackback状态(open/closed)
post_password 文章密码
post_name 文章缩略名
to_ping 要引用的URL链接
pinged 已经PING过的链接
post_modified 修改时间
post_modified_gmt 修改时间(GMT+0时间)
post_content_filtered 未知
post_parent 父文章,主要用于PAGE
guid 文章的一个链接。注意:不能将GUID作为永久链接(虽然在2.5之前的版本中它的确被当作永久链接),也不能将它作为文章的可用链接。GUID是一种独有的标识符,只是目前恰巧成为文章的一个链接。
menu_order 排序ID
post_type 文章类型(post/page/attachment/revision等)
post_mime_type MIME类型
comment_count 评论总数

由此可以看到,Wordpress 利用 post_type 可以在该表中存储草稿、文章、页面、附件等丰富的信息,一张表就搞定了。

wp_postmeta 表

与这张表相关联的,还有一个 wp_postmeta 表,用来存储与文章相关的元数据。这个表的表结构比较简单。

字段 含义
meta_id 元数据记录的ID。
post_id 就是元数据相关联的post,用户(user),评论(comment)的ID。
meta_key 元键(meta key)(这个值在不同的记录中经常是重复的)。
meta_value 元值(meta value)(往往是唯一的)。

如何获取特色图像 Featured Image

那么,对于一个文章,是如何来获取特色图像 Featured Image的,下面来看一下。在后台的文章编辑界面,特色图像显示在这个位置。

对应的后台代码是 wp-admin/includes/meta-boxes.php

/**
 * Display post thumbnail meta box.
 *
 * @since 2.9.0
 *
 * @param WP_Post $post A post object.
 */
function post_thumbnail_meta_box( $post ) {
    $thumbnail_id = get_post_meta( $post->ID, '_thumbnail_id', true );    //获取特色图像对应的ID
    echo _wp_post_thumbnail_html( $thumbnail_id, $post->ID );    //输出HTML
}

继续找 get_post_meta ,在wp-includes/post.php中。

/**
 * Retrieve post meta field for a post.
 *
 * @since 1.5.0
 *
 * @param int    $post_id Post ID.
 * @param string $key     Optional. The meta key to retrieve. By default, returns
 *                        data for all keys. Default empty.
 * @param bool   $single  Optional. Whether to return a single value. Default false.
 * @return mixed Will be an array if $single is false. Will be value of meta data
 *               field if $single is true.
 */
function get_post_meta( $post_id, $key = '', $single = false ) {
    return get_metadata('post', $post_id, $key, $single);
}

继续找 get_metadata 在 wp-includes/meta.php 中。

/**
 * Retrieve metadata for the specified object.
 *
 * @since 2.9.0
 *
 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
 * @param int    $object_id ID of the object metadata is for
 * @param string $meta_key  Optional. Metadata key. If not specified, retrieve all metadata for
 *                             the specified object.
 * @param bool   $single    Optional, default is false.
 *                          If true, return only the first value of the specified meta_key.
 *                          This parameter has no effect if meta_key is not specified.
 * @return mixed Single metadata value, or array of values
 */
function get_metadata($meta_type, $object_id, $meta_key = '', $single = false) {
    if ( ! $meta_type || ! is_numeric( $object_id ) ) {
        return false;
    }

    $object_id = absint( $object_id );
    if ( ! $object_id ) {
        return false;
    }
    //echo $object_id . ':' . $meta_type . '-' . $meta_key . '-' . $single . '<br />';
    /**
     * Filters whether to retrieve metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|array|string $value     The value get_metadata() should return - a single metadata value,
     *                                     or an array of values.
     * @param int               $object_id Object ID.
     * @param string            $meta_key  Meta key.
     * @param bool              $single    Whether to return only the first value of the specified $meta_key.
     */
    $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );
    if ( null !== $check ) {
        if ( $single && is_array( $check ) )
            return $check[0];
        else
            return $check;
    }

    $meta_cache = wp_cache_get($object_id, $meta_type . '_meta');

    if ( !$meta_cache ) {
        $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
        $meta_cache = $meta_cache[$object_id];
    }

    if ( ! $meta_key ) {
        return $meta_cache;
    }

    if ( isset($meta_cache[$meta_key]) ) {
        if ( $single )
            return maybe_unserialize( $meta_cache[$meta_key][0] );
        else
            return array_map('maybe_unserialize', $meta_cache[$meta_key]);
    }

    if ($single)
        return '';
    else
        return array();
}

这个函数中会根据 $meta_key 和 $object_id 、$meta_type 取出特色图像对应的ID。为了避免重复读取数据库,这里用了缓存,我们可以看 update_meta_cache 这个函数。

/**
 * Update the metadata cache for the specified objects.
 *
 * @since 2.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string    $meta_type  Type of object metadata is for (e.g., comment, post, or user)
 * @param int|array $object_ids Array or comma delimited list of object IDs to update cache for
 * @return array|false Metadata cache for the specified objects, or false on failure.
 */
function update_meta_cache($meta_type, $object_ids) {
    global $wpdb;

    if ( ! $meta_type || ! $object_ids ) {
        return false;
    }

    $table = _get_meta_table( $meta_type );
    if ( ! $table ) {
        return false;
    }

    $column = sanitize_key($meta_type . '_id');

    if ( !is_array($object_ids) ) {
        $object_ids = preg_replace('|[^0-9,]|', '', $object_ids);
        $object_ids = explode(',', $object_ids);
    }

    $object_ids = array_map('intval', $object_ids);

    $cache_key = $meta_type . '_meta';
    $ids = array();
    $cache = array();
    foreach ( $object_ids as $id ) {
        $cached_object = wp_cache_get( $id, $cache_key );
        if ( false === $cached_object )
            $ids[] = $id;
        else
            $cache[$id] = $cached_object;
    }

    if ( empty( $ids ) )
        return $cache;

    // Get meta info
    $id_list = join( ',', $ids );
    $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
    echo "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC" . "<br />";
    $meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A );

    if ( !empty($meta_list) ) {
        foreach ( $meta_list as $metarow) {
            $mpid = intval($metarow[$column]);
            $mkey = $metarow['meta_key'];
            $mval = $metarow['meta_value'];

            // Force subkeys to be array type:
            if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) )
                $cache[$mpid] = array();
            if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) )
                $cache[$mpid][$mkey] = array();

            // Add a value to the current pid/key:
            $cache[$mpid][$mkey][] = $mval;
        }
    }

    foreach ( $ids as $id ) {
        if ( ! isset($cache[$id]) )
            $cache[$id] = array();
        wp_cache_add( $id, $cache[$id], $cache_key );
    }

    return $cache;
}

关键的语句在这里

SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (21) ORDER BY meta_id ASC

可以看到结果如下,_thumbnail_id 对应的就是 wp_posts 中的记录ID,从而可以取到图片对应的地址和相关信息。

本文内容基于 Wordpress 4.8版本

参考资料:
1、如何设置Wordpress的特色图像
2、WordPress数据库表及字段详解
3、理解和利用 WordPress 中的元数据(Metadata)

时间: 2024-10-26 08:18:02

Wordpress中文章的特色图像Featured Image究竟存在哪里?的相关文章

优化WordPress中文章与评论的时间显示_php技巧

很多博客都喜欢用 评论发表于 "XXX 分钟 之前".文章发表于 "XXX 分钟 之前"来显示文章评论的时间,改善的时间显示方式不仅能很直观的告诉读者这篇文章或评论发表距今已有多长时间,更能增强评论回复的时间感,哥很喜欢,因为前一阵子压在手里的东西太多了,工作日白天又苦于不能上网,所以主题的样式及功能部分一点一点的写拖了好长时间,最近这阵子刚好轮到折腾评论了,所以就逐步参照网上流行的样式一点一点的修改起来自己的评论样式和功能. So-.. Go-.. 交道麻袋-..

WordPress如何获取文章内容页特色图像地址

WordPress获取特色图像地址主要需要用到两个函数get_post_thumbnail_id和wp_get_attachment_image_src.下面是分别获取小.中.大.完整.指定图片规格的图片地址的方法. 获取特色图像:指定100x100 <?php $array_image_url = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), array(100,100)); echo $array_image_

WordPress中卸载插件以及移除文章类型组件的代码示例_java

插件卸载在开发插件的过程中,免不了在数据库创建一些字段乃至表,或者创建了一些定时任务,当插件被删除的时候这些东西就会被留在 WordPress 上,变成垃圾,作为负责的开发者,有必要在删除插件的时候帮助用户删除掉我们留下的痕迹. uninstall.php 文件 做到这点有两种方法,一时在插件的根目录创建一个 uninstall.php 文件,在你的插件被删除之前会调用执行这个文件,但要注意就是防止有人恶意访问这个文件我们需要判断一下 WP_UNINSTALL_PLUGIN 常量是否被定义,没定

wordpress取得文章中第一张图片url地址的函数

wordpress取得文章中第一张图片url:  代码如下 复制代码 function catch_that_image() {  global $post, $posts;  $first_img = '';  ob_start();  ob_end_clean();  $output = preg_match_all('/<img.+src=['"]([^'"]+)['"].*>/i', $post->post_content, $matches);  

在WordPress的文章编辑器中设置默认内容的方法_php实例

很多时候我们需要在给 WordPress 文章编辑器设置默认内容,比如把常用的开头或者文章注意事项放进去,本文就教你给 WordPress 编辑器设置默认内容. /** *WordPress 给文章编辑器设置默认内容 *http://www.endskin.com/default-content-title/ */ function Bing_default_content(){ return '要设置的默认内容'; } add_filter( 'default_content', 'Bing_

WordPress发布文章即时推送到百度,加快百度收录

一.主动推送 先来看下百度对于主动推送的一些说明:     主动推送:最为快速的提交方式,建议您将站点当天新产出链接立即通过此方式推送给百度,以保证新链接可以及时被百度收录.     主动推送支持多种途径:比如curl .post.php以及ruby等.而且支持一次性提交多条网站页面地址,不过每个站点每天可推送的次数暂时限制在50次.    使用主动推送功能会达到怎样效果?    ①.及时发现:可以缩短百度爬虫发现您站点新链接的时间,使新发布的页面可以在第一时间被百度收录    ②.保护原创:对

解析WordPress中的post_class与get_post_class函数_php技巧

post_class()post_class 是 WordPress 内置的一个用于显示文章 class 名称的函数,该函数通常会为每一篇文章生成独一无二的 clss 值,如果你需要制作你自己的主题,而且还需要一点个性的话,那你最好驻足一下,使用该函数并配合灵活的 css 代码,我们可以制作出个性化十足的 WordPress 博客. post_class 函数描述 该函数通常会为每一篇文章生成独一无二的 clss 值,可以很方便使用于文章所在的节点中. 函数使用 向其他的诸如 header_im

详解WordPress中分类函数wp_list_categories的使用_php技巧

wp_list_categories 函数是 WordPress 中用来罗列系统中分类的函数,该函数拥有许多控制输出的参数,今天突然被一个朋友问到,所以就大概整理了一下. 因为 WordPress 中内置扩展的小工具功能, 所以我们不经任何函数就可以在边栏或是其他我们想要的位置显示一个分类列表, 所以wp_list_categories函数就很少有人用到, 该函数使用起来有点类似于wp_list_bookmarks, wp_list_categories 描述wp_list_categories

完美实现wordpress禁止文章修订和自动保存的方法_php实例

使用Wordpress这么久一直很讨厌wordpress的文章修订和自动保存功能,也使用过超级开关插件可以禁止wordpress文章修订和自动保存功能,但是自己博客的插件已经够多的了,只好通过修改wordpress主程序来实现禁止文章修订和自动保存功能.但是这种方法有个不好的地方就是,每次wordpress升级,就得再改动一次wordpress源码,实在是很麻烦的.今天无意中撞到了ZWW博客上发现这个非插件免修改源码实现wordpress禁止文章修订和自动保存的方法,分享给大家吧! 使用方法很简