各位观众老爷们,大家好!今天咱们来聊聊 WordPress 里面那个默默奉献、记录你每一次修改的“小本本”—— wp_post_revisions
表。 别看它名字叫“修订”,其实它干的活儿可不简单,相当于你的文章时光机,让你随时可以回到过去,找回灵感迸发的瞬间,或者手滑删掉的重要段落。
咱们今天就来扒一扒这个 wp_post_revisions
表的源码,看看它到底是怎么实现文章修订功能的。Let’s dive in!
一、wp_post_revisions
表:数据结构和存储逻辑
首先,我们得搞清楚 wp_post_revisions
表里都存了些什么。打开你的数据库,瞧一眼它的结构,你会发现它跟 wp_posts
表长得很像,毕竟它就是 wp_posts
表的一个“影子”。
以下是一个简化的 wp_posts
表和 wp_post_revisions
表的对比,方便大家理解:
字段名 | wp_posts 表 (主表) |
wp_post_revisions 表 (修订表) |
备注 |
---|---|---|---|
ID |
文章唯一ID | 修订版本唯一ID | 都是自增主键,但修订版本的ID跟文章ID没有直接关系。 |
post_author |
作者ID | 作者ID | 修订版本通常与文章作者相同。 |
post_date |
发布日期 | 修订日期 | 修订日期记录的是这个版本创建的时间,通常跟文章的最后修改时间接近。 |
post_date_gmt |
发布日期 (GMT) | 修订日期 (GMT) | 同上,只是用了 GMT 时区。 |
post_content |
文章内容 | 修订版本的内容 | 存储了对应修订版本的文章内容,这是最重要的部分。 |
post_title |
文章标题 | 修订版本的标题 | 存储了对应修订版本的文章标题。 |
post_excerpt |
文章摘要 | 修订版本的摘要 | 存储了对应修订版本的文章摘要。 |
post_status |
文章状态 | inherit |
修订版本的状态始终是 inherit ,表示继承自父文章。 |
comment_status |
评论状态 | 与父文章相同 | |
ping_status |
Pingback 状态 | 与父文章相同 | |
post_password |
文章密码 | 与父文章相同 | |
post_name |
文章别名 | 修订版本的别名 | 修订版本的别名通常是文章别名加上一个修订版本号,例如 my-post-revision-v1 。 |
to_ping |
要 Ping 的 URL | 与父文章相同 | |
pinged |
已 Ping 的 URL | 与父文章相同 | |
post_modified |
最后修改日期 | 修订版本的修改日期 | |
post_modified_gmt |
最后修改日期 (GMT) | 修订版本的修改日期 (GMT) | |
post_content_filtered |
过滤后的内容 | 修订版本过滤后的内容 | |
post_parent |
父文章ID | 父文章ID | 指向主文章的ID,将修订版本与主文章关联起来。 |
guid |
GUID (全局唯一标识符) | 修订版本的GUID | |
menu_order |
菜单顺序 | 与父文章相同 | |
post_type |
文章类型 | revision |
修订版本的文章类型始终是 revision 。 |
post_mime_type |
MIME 类型 | 与父文章相同 | |
comment_count |
评论数 | 与父文章相同 |
从上面的表格可以看出,wp_post_revisions
表存储了文章的各个修订版本,每个版本都包含文章的完整内容、标题、摘要等信息。 关键的一点是 post_parent
字段,它指向了主文章的 ID
,通过这个字段,WordPress 就能把所有的修订版本跟对应的文章关联起来。
二、WordPress 如何创建和管理修订版本?
好,了解了数据结构,接下来我们就看看 WordPress 是怎么创建和管理这些修订版本的。
1. 触发修订版本创建的时机
一般来说,以下几种情况会触发 WordPress 创建新的修订版本:
- 自动保存 (autosave): WordPress 会定期自动保存你的文章,防止你辛辛苦苦码的字因为意外情况丢失。 自动保存的版本也是一个修订版本,但它的
post_status
是auto-draft
,而且通常不会显示在修订版本列表中。 - 手动保存/发布: 当你点击“保存草稿”、“发布”或者“更新”按钮时,WordPress 也会创建一个新的修订版本。
2. 核心函数:wp_insert_post()
创建修订版本的核心函数是 wp_insert_post()
, 这个函数负责插入或更新 wp_posts
表中的数据,包括文章和修订版本。 让我们看看 wp_insert_post()
里面跟修订版本相关的代码片段:
function wp_insert_post( $postarr = array(), $wp_error = false ) {
// ... 一大堆代码 ...
// 如果是更新文章,并且需要创建修订版本
if ( ! empty( $post_ID ) ) {
$post_before = get_post( $post_ID );
// 检查是否需要创建修订版本 (例如,内容是否发生变化)
if ( wp_revisions_enabled( $post_before ) && apply_filters( 'wp_save_post_revision_check_for_changes', did_action( 'edit_post' ), $post_before, $postarr ) ) {
$revision_id = wp_save_post_revision( $post_ID, 'revision' ); // 创建修订版本
if ( is_wp_error( $revision_id ) ) {
return $revision_id;
}
$revisions[] = $revision_id;
}
}
// ... 更多代码 ...
return $post_ID;
}
这段代码的核心在于 wp_save_post_revision()
函数,它才是真正创建修订版本的“幕后黑手”。
3. 创建修订版本的关键:wp_save_post_revision()
wp_save_post_revision()
函数负责将当前的文章数据复制一份,然后插入到 wp_post_revisions
表中。 我们来深入了解一下这个函数的实现:
function wp_save_post_revision( $post_id, $revision = 'revision' ) {
$post = get_post( $post_id );
if ( is_wp_error( $post ) ) {
return $post;
}
// 准备修订版本的数据
$revision_data = array(
'post_title' => $post->post_title,
'post_content' => $post->post_content,
'post_excerpt' => $post->post_excerpt,
'post_author' => $post->post_author,
'post_status' => 'inherit', // 修订版本的状态总是 'inherit'
'post_type' => 'revision', // 修订版本的类型总是 'revision'
'post_name' => $post->post_name, // 修订版本的别名
'post_parent' => $post->ID, // 指向父文章的ID
'post_date' => $post->post_date,
'post_date_gmt' => $post->post_date_gmt,
'post_modified' => current_time( 'mysql' ),
'post_modified_gmt' => current_time( 'mysql', 1 ),
);
// 根据 $revision 参数,设置修订版本的后缀 (例如,'revision', 'autosave')
if ( 'autosave' == $revision ) {
$revision_data['post_name'] = $post->post_name . '-autosave';
} else {
$revision_data['post_name'] = $post->post_name . '-revision';
}
// 插入修订版本到数据库
$revision_id = wp_insert_post( $revision_data );
if ( is_wp_error( $revision_id ) ) {
return $revision_id;
}
// 更新修订版本的 GUID
$guid = get_permalink( $revision_id );
wp_update_post( array( 'ID' => $revision_id, 'guid' => $guid ) );
return $revision_id;
}
这个函数做了以下几件事:
- 获取文章数据: 通过
get_post()
函数获取当前文章的所有数据。 - 准备修订版本数据: 创建一个数组
$revision_data
,包含文章的标题、内容、摘要、作者、状态、类型等信息。 注意,修订版本的post_status
始终是inherit
,post_type
始终是revision
,post_parent
指向父文章的 ID。 - 设置修订版本别名: 根据
$revision
参数,设置修订版本的别名,通常是在文章别名后面加上-revision
或-autosave
。 - 插入修订版本到数据库: 调用
wp_insert_post()
函数,将$revision_data
插入到wp_post_revisions
表中,创建一个新的修订版本。 - 更新修订版本的 GUID: 更新修订版本的 GUID,确保每个修订版本都有一个唯一的 URL。
三、WordPress 如何显示和比较修订版本?
创建了修订版本之后,WordPress 还需要提供一个界面,让用户可以查看、比较和恢复这些版本。
1. 获取文章的修订版本:wp_get_post_revisions()
wp_get_post_revisions()
函数用于获取指定文章的所有修订版本。 它会查询 wp_post_revisions
表,并返回一个包含所有修订版本对象的数组。
function wp_get_post_revisions( $post_id = 0, $args = array() ) {
$defaults = array(
'posts_per_page' => -1, // 获取所有修订版本
'fields' => '', // 获取所有字段
'orderby' => 'post_modified', // 按照修改时间排序
'order' => 'DESC', // 倒序排列
'post_status' => 'inherit', // 只获取状态为 'inherit' 的修订版本
'post_type' => 'revision', // 只获取类型为 'revision' 的修订版本
);
$args = wp_parse_args( $args, $defaults );
$args['post_parent'] = $post_id; // 设置父文章ID,只获取指定文章的修订版本
$revisions = get_children( $args ); // 调用 get_children() 函数获取修订版本
return $revisions;
}
这个函数的核心是 get_children()
函数,它用于获取指定父文章的所有子文章,也就是修订版本。
2. 显示修订版本列表
在文章编辑页面,你会看到一个“修订”面板,里面列出了文章的所有修订版本。 这个面板通常会显示修订版本的修改日期和作者,方便你选择要查看的版本。
WordPress 使用 wp_list_post_revisions()
函数来生成修订版本列表的 HTML 代码。
3. 比较修订版本:wp_get_revision_ui_diff()
WordPress 提供了一个强大的修订版本比较功能,可以让你清楚地看到不同版本之间的差异。 这个功能的核心是 wp_get_revision_ui_diff()
函数,它使用 PHP 的 wp_text_diff()
函数来生成差异对比的 HTML 代码。
function wp_get_revision_ui_diff( $left, $right, $args = array() ) {
$defaults = array(
'show_split_view' => true, // 是否显示分屏对比
);
$args = wp_parse_args( $args, $defaults );
$left_content = $left->post_content;
$right_content = $right->post_content;
$diff = wp_text_diff( $left_content, $right_content, $args ); // 使用 wp_text_diff() 函数生成差异对比
return $diff;
}
wp_text_diff()
函数会将两个版本的文章内容进行比较,并生成一个 HTML 表格,用不同的颜色标记出新增、删除和修改的部分。 这样你就可以一目了然地看到两个版本之间的差异。
4. 恢复修订版本
如果你想恢复到某个旧的修订版本,只需点击“恢复”按钮,WordPress 就会将该版本的内容复制到主文章中。 这个过程实际上就是将修订版本的 post_content
、post_title
等字段的值更新到主文章的对应字段中。
四、修订版本的优化和管理
虽然修订版本功能非常有用,但过多的修订版本也会占用大量的数据库空间,影响网站的性能。 因此,我们需要对修订版本进行优化和管理。
1. 限制修订版本的数量
WordPress 允许你限制每个文章保存的修订版本数量。 你可以在 wp-config.php
文件中添加以下代码来设置修订版本的最大数量:
define( 'WP_POST_REVISIONS', 3 ); // 最多保存 3 个修订版本
如果你想禁用修订版本功能,可以将 WP_POST_REVISIONS
设置为 false
:
define( 'WP_POST_REVISIONS', false ); // 禁用修订版本功能
2. 定期清理旧的修订版本
即使你限制了修订版本的数量,时间长了,数据库中仍然会积累大量的旧版本。 你可以使用一些插件或者手动编写 SQL 语句来清理这些旧版本。
以下是一个清理旧修订版本的 SQL 语句:
DELETE FROM wp_posts
WHERE post_type = 'revision'
AND post_date < DATE_SUB(CURDATE(), INTERVAL 30 DAY); -- 删除 30 天前的修订版本
3. 使用插件进行管理
有很多 WordPress 插件可以帮助你更好地管理修订版本,例如:
- WP-Sweep: 可以清理未使用的修订版本、自动草稿、垃圾评论等,优化数据库。
- Optimize Database after Deleting Revisions: 专门用于优化数据库,删除旧的修订版本。
- Revision Control: 可以更精细地控制每个文章类型的修订版本数量。
五、总结
好了,各位观众老爷们,今天我们深入剖析了 WordPress 的 wp_post_revisions
表,了解了它是如何实现文章修订功能的。 从数据结构到创建、显示、比较和管理,我们都进行了详细的讲解。
希望通过今天的讲座,大家对 WordPress 的修订版本功能有了更深入的理解。 记住,wp_post_revisions
表是你的文章时光机,善用它,可以让你更好地管理你的内容,找回灵感,避免损失。
下次再见!