使用Wordpress,尤其从3.0走入Wordpress世界的朋友,也许都遇到过一个问题:自动保存(Auto-Save)和文章修订(Post-Revisioning)功能导致文章ID不连续的问题。有时还特别夸张。例如,我的“‘地瓜哥’博客网”,第一篇文章是1,第二篇文章已经一下子跳到了19。这样对于像D瓜哥这样的“ID洁癖”的人来说,实在很不爽!经过D瓜哥的多次尝试后,终于很彻底地解决了这个问题。并且,还可以把以前被自动备份的ID重新利用起来!
去掉自动草稿的功能
造成发布文章ID不连续的原因有三:
- 自动保存功能 Auto-Save;
- 历史版本 Post Revisions;
- 自动草稿功能 Auto-Draft!
针对WordPress 3.4.x,这里给大家介绍一个解决ID不连续发方法:
- 打开%WP%/wp-config.php文件,在 “$table_prefix = ‘wp_’;” 前面添加如下代码(注意,一定是”$table_prefix = ‘wp_’;”这行的前面):
1 | define( 'WP_POST_REVISIONS' , false); |
2 | define( 'AUTOSAVE_INTERVAL' , false); |
- 找到并打开%WP%/wp-admin/post-new.php 和%WP%/wp-admin/post.php 这两个文件,将其 “wp_enqueue_script(‘autosave’);” 注释或删除掉。如下:
经过上面的修改后,文章的自动保存和历史版本都关闭了。不过,这里也带来了一个副作用:预览不能使用了,需要手动保存草稿后才行。美中不足吧。
另外,还有个自动草稿功能,我们下面会介绍如何处理。
在这里D瓜哥要纠正一个曾经犯的错误。D瓜哥在“关闭WordPress自动保存和文章修订功能”中提到了一种方法,但是经过D瓜哥的使用经验来看,这种方式不好使!请大家停止使用。
删除无用的草稿
在“删除草稿”方面,有一些相应的插件,比如Delete-Revision,但是给Wordpress安装过多的插件会降低她的速度。所以,D瓜哥尽量少安装插件,如果通过简单的代码修改就能解决问题,就尽量修改代码。另外,由于“删除草稿”这样的操作,也许只需要操作一次,而且只需要简单的SQL。所以,D瓜哥认为必要安装插件。这次,我们就通过编码来完成我们的工作。
注意,请在进行如下工作前,备份数据库!防止把数据搞坏。
我们先来看一下冗余数据(无用的自动修订、草稿等)。登陆phpMyAdmin(一般虚拟主机都会提供的),然后选中相应的数据库,然后在里面执行如下SQL:
3 | SELECT * FROM `wp_posts` WHERE `post_type` = 'revision' ; |
这里显示内容都是一些冗余的数据,可以直接删除。删除SQL如下:
2 | DELETE FROM `wp_posts` WHERE `post_type` = 'revision' ; |
另外,需要给大家提醒一点。在D瓜哥查找删除冗余数据的资料中,见到过如下的写法:
1 | DELETE FROM `wp_posts` WHERE `post_status` != 'publish' OR `post_type` = 'revision' ; |
经过D瓜哥对实际数据的观察发现,这个SQL是不对的。它会把上传的图片等信息删除掉。所以,请大家注意!!
经过这次清理后,数据库干净了许多。同时,也在表中的ID不再连续,还空出来好多没被用掉的ID数。那么,我们该如何重用这些被空出来的ID呢?
重用被浪费掉的ID
根据D瓜哥的个人经验,Wordpress会每隔一段时间,自动在wp_posts表中添加一条草稿记录。并且,对于用户来说是不可见的。这也是一种浪费。浪费的还有上一节被删掉后空出来的ID。所以,有必要想办法重新这些被浪费掉的ID。
重用自动草稿产生的ID
既然,Wordpress能产生不可见的草稿记录。那么,我们修改一下代码,在添加文章的时候,把自动产生的草稿记录读取出来,重新添加文章内容即可。下面,D瓜哥给大家介绍一下方法:
打开%WP%/wp-admin/includes/post.php文件,将如下内容(Wordpress 3.4.2):
3 | $post_id = wp_insert_post( array ( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type , 'post_status' => 'auto-draft' ) ); |
4 | $post = get_post( $post_id ); |
5 | if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post ->post_type, 'post-formats' ) && get_option( 'default_post_format' ) ) |
6 | set_post_format( $post , get_option( 'default_post_format' ) ); |
替换为如下内容:
04 | $post = $wpdb ->get_row( "SELECT * FROM $wpdb->posts WHERE post_status = 'auto-draft' AND post_type = '$post_type' AND post_author = $current_user->ID ORDER BY post_date ASC, ID ASC LIMIT 1" ); |
06 | $post_id = wp_insert_post( array ( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type , 'post_status' => 'auto-draft' ) ); |
07 | $post = get_post( $post_id ); |
10 | if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post ->post_type, 'post-formats' ) && get_option( 'default_post_format' ) ) |
11 | set_post_format( $post , get_option( 'default_post_format' ) ); |
请注意上面代码中使用的SQL语句:
1 | SELECT * FROM $wpdb->posts WHERE post_status = 'auto-draft' AND post_type = '$post_type' AND post_author = $ current_user ->ID ORDER BY post_date ASC , ID ASC LIMIT 1 |
这里,之所以使用post_date排序,是因为自动草稿超过七天后会自动删除。所以,先使用比较旧的记录。可能,你会问,那不是有ID在排序吗?这个问题,我们在下一小节再解释。
生成添加“草稿”的数据
经过上面的折腾,空出来一些ID。既然自动草稿的记录能使用,那么空出来的ID更加可以随意使用。现在,我们就想办法把这些空出来的ID也使用起来。
根据网友测试结果显示,经过修改上面的代码修改后,只要手动保持wp_posts表中数据的三个字段内容如下,那么这些空出来的ID也可以被使用起来。
1 | post_status='auto-draft' |
8 | // post_author字段也要填上相应作者的ID。 |
将空出来的ID分别安装上面的要求,将对应一列数据造出来即可。我们上面提到,Wordpress会自动添加自动草稿的记录,并且七天后就自动删除。那么,我们要在两个时间相关的字段post_date和post_modified上,填上一个尽可能打一点的值,防止Wordpress自动删除。但是,系统还有可能产生自动草稿。那么,为了防止被删除,系统产生的这些自动草稿记录要优先使用掉。所以,我们上面的SQL中,有按照时间排序的条件。
既然有了上面这些要求,那么我们就写一个SQL语句,来自动生成数据。SQL如下:
02 | CREATE TABLE post_bk as |
04 | 'auto-draft' as post_status, |
08 | str_to_date( '11.25.2015 00:00:00' , |
09 | '%m.%d.%Y %H:%i:%s' ) as post_date, |
10 | str_to_date( '03.26.2015 21:44:00' , |
11 | '%m.%d.%Y %H:%i:%s' ) as post_modified |
12 | from ( select b.dd * 10 + a.dd as iid |
22 | union all select 9) a, |
34 | WHERE iid > 0 and iid NOT IN |
35 | ( SELECT ID from wp_posts ) |
这个SQL语句只能生成100以内的空ID的记录;另外,这里制造100以内的整数时,有点麻烦,可以考虑直接用编程语言生成以逗号分隔的数字序列。
这个生成工作最好在本地进行。生成完后,使用phpMyAdmin将生成出来的post_bk表的数据都导出成脚本,然后登陆服务器上的phpMyAdmin,将脚本导入到服务器上的表中。
这里,给大家展示两条我导出出来的数据。需要的话,直接拷贝使用:
2 | INSERT INTO `wp_posts` (`ID`, `post_status`, `guid`, `post_type`, `post_author`, `post_date`, `post_modified`) VALUES (3, 'auto-draft' , 'http://www.diguage.com/?p=3' , 'post' , 1, '2015-11-25 00:00:00' , '2015-03-26 21:44:00' ); |
3 | INSERT INTO `wp_posts` (`ID`, `post_status`, `guid`, `post_type`, `post_author`, `post_date`, `post_modified`) VALUES (4, 'auto-draft' , 'http://www.diguage.com/?p=4' , 'post' , 1, '2015-11-25 00:00:00' , '2015-03-26 21:44:00' ); |
参考资料
- WordPress 3.4.1关闭自动草稿、自动保存和禁用文章修订版
- WordPress 3.4.2、3.5文章ID连续方法—禁用自动草稿、自动保存和文章修订
- wordpress插件清理自动保存多版本草稿及关闭方法
- Delete-Revision插件
太麻烦了,懒得弄了
@常青 可以考虑使用Delete-Revision插件,偶尔删除一下就可以了。对于使用wordpress默认编辑器写文章的朋友,建议不要关闭自动保存
我不想装插件了,所以就自己吓倒腾了。哈哈
确认非常之麻烦。一般人也就是写个博客而已,最多注意下排版就了不得了。
这个不错,这样的话,以后首页文章的排序就可以按照ID的奇偶数设置不同的样式了
对于空余id的利用很重要,能不能写个function语言,简化操作困难度。
最新的版本用这个不行。
确实不行!
我不是沙发,但我顶楼主!
感谢,刚才试了,只不过最新版WP似乎有点问题。