WordPress折腾小记:彻底解决ID不连续的问题
使用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_’;”这行的前面):
- 找到并打开%WP%/wp-admin/post-new.php 和%WP%/wp-admin/post.php 这两个文件,将其 “wp_enqueue_script(‘autosave’);” 注释或删除掉。如下:
define('WP_POST_REVISIONS', false); define('AUTOSAVE_INTERVAL', false);
//wp_enqueue_script('autosave');
经过上面的修改后,文章的自动保存和历史版本都关闭了。不过,这里也带来了一个副作用:预览不能使用了,需要手动保存草稿后才行。美中不足吧。
另外,还有个自动草稿功能,我们下面会介绍如何处理。
在这里D瓜哥要纠正一个曾经犯的错误。D瓜哥在“关闭WordPress自动保存和文章修订功能”中提到了一种方法,但是经过D瓜哥的使用经验来看,这种方式不好使!请大家停止使用。
删除无用的草稿
在“删除草稿”方面,有一些相应的插件,比如Delete-Revision,但是给Wordpress安装过多的插件会降低她的速度。所以,D瓜哥尽量少安装插件,如果通过简单的代码修改就能解决问题,就尽量修改代码。另外,由于“删除草稿”这样的操作,也许只需要操作一次,而且只需要简单的SQL。所以,D瓜哥认为必要安装插件。这次,我们就通过编码来完成我们的工作。
注意,请在进行如下工作前,备份数据库!防止把数据搞坏。
我们先来看一下冗余数据(无用的自动修订、草稿等)。登陆phpMyAdmin(一般虚拟主机都会提供的),然后选中相应的数据库,然后在里面执行如下SQL:
-- 查看自动修订产生的冗余数据 -- 注意,请根据自己的情况,修改表名(主要是表前缀) SELECT * FROM `wp_posts` WHERE `post_type` = 'revision';
这里显示内容都是一些冗余的数据,可以直接删除。删除SQL如下:
-- 删除冗余数据 DELETE FROM `wp_posts` WHERE `post_type` = 'revision';
另外,需要给大家提醒一点。在D瓜哥查找删除冗余数据的资料中,见到过如下的写法:
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):
// 原始Wordpress代码 if ( $create_in_db ) { $post_id = wp_insert_post( array( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type, 'post_status' => 'auto-draft' ) ); $post = get_post( $post_id ); if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) ) set_post_format( $post, get_option( 'default_post_format' ) ); } else {
替换为如下内容:
// 替换后,可以重用自动草稿 if ( $create_in_db ) { global $current_user; // 获取当前登录管理用户 $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" ); // 获取最早一条自动草稿 if ( !$post ) { $post_id = wp_insert_post( array( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type, 'post_status' => 'auto-draft' ) ); $post = get_post( $post_id ); } if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) ) set_post_format( $post, get_option( 'default_post_format' ) ); } else {
请注意上面代码中使用的SQL语句:
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也可以被使用起来。
post_status='auto-draft' guid='http://youdomain/?p={$ID}' post_type='post' // ID不能为空,还有和{$ID}保持一致; ID // post_author字段也要填上相应作者的ID。 post_author
将空出来的ID分别安装上面的要求,将对应一列数据造出来即可。我们上面提到,Wordpress会自动添加自动草稿的记录,并且七天后就自动删除。那么,我们要在两个时间相关的字段post_date和post_modified上,填上一个尽可能打一点的值,防止Wordpress自动删除。但是,系统还有可能产生自动草稿。那么,为了防止被删除,系统产生的这些自动草稿记录要优先使用掉。所以,我们上面的SQL中,有按照时间排序的条件。
既然有了上面这些要求,那么我们就写一个SQL语句,来自动生成数据。SQL如下:
-- 生成100以内的空ID对应的记录 CREATE TABLE post_bk as SELECT iid AS ID, 'auto-draft' as post_status, CONCAT('http://www.diguage.com/?p=', iid) AS guid, 'post' AS post_type, 1 as post_author, str_to_date('11.25.2015 00:00:00', '%m.%d.%Y %H:%i:%s') as post_date, str_to_date('03.26.2015 21:44:00', '%m.%d.%Y %H:%i:%s') as post_modified from ( select b.dd * 10 + a.dd as iid from ( select 1 as dd union all select 2 union all select 3 union all select 4 union all select 0 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) a, (select 0 as dd union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) b ) num WHERE iid > 0 and iid NOT IN ( SELECT ID from wp_posts ) ORDER BY iid ASC;
这个SQL语句只能生成100以内的空ID的记录;另外,这里制造100以内的整数时,有点麻烦,可以考虑直接用编程语言生成以逗号分隔的数字序列。
这个生成工作最好在本地进行。生成完后,使用phpMyAdmin将生成出来的post_bk表的数据都导出成脚本,然后登陆服务器上的phpMyAdmin,将脚本导入到服务器上的表中。
这里,给大家展示两条我导出出来的数据。需要的话,直接拷贝使用:
-- 添加空白记录对应,重用ID 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'); 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插件
原文链接:https://wordpress.diguage.com/archives/5.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
太麻烦了,懒得弄了
@常青 可以考虑使用Delete-Revision插件,偶尔删除一下就可以了。对于使用wordpress默认编辑器写文章的朋友,建议不要关闭自动保存
我不想装插件了,所以就自己吓倒腾了。哈哈
确认非常之麻烦。一般人也就是写个博客而已,最多注意下排版就了不得了。
这个不错,这样的话,以后首页文章的排序就可以按照ID的奇偶数设置不同的样式了
对于空余id的利用很重要,能不能写个function语言,简化操作困难度。
最新的版本用这个不行。
确实不行!
我不是沙发,但我顶楼主!
感谢,刚才试了,只不过最新版WP似乎有点问题。