首页 > Web开发, 挨踢(IT) > WordPress折腾小记:彻底解决ID不连续的问题

WordPress折腾小记:彻底解决ID不连续的问题

2013年4月1日 发表评论 阅读评论 1,829 人阅读    

  使用Wordpress,尤其从3.0走入Wordpress世界的朋友,也许都遇到过一个问题:自动保存(Auto-Save)和文章修订(Post-Revisioning)功能导致文章ID不连续的问题。有时还特别夸张。例如,我的“‘地瓜哥’博客网”,第一篇文章是1,第二篇文章已经一下子跳到了19。这样对于像D瓜哥这样的“ID洁癖”的人来说,实在很不爽!经过D瓜哥的多次尝试后,终于很彻底地解决了这个问题。并且,还可以把以前被自动备份的ID重新利用起来!

去掉自动草稿的功能

  造成发布文章ID不连续的原因有三:

  1. 自动保存功能 Auto-Save;
  2. 历史版本 Post Revisions;
  3. 自动草稿功能 Auto-Draft!

  针对WordPress 3.4.x,这里给大家介绍一个解决ID不连续发方法:

  1. 打开%WP%/wp-config.php文件,在 “$table_prefix = ‘wp_’;” 前面添加如下代码(注意,一定是”$table_prefix = ‘wp_’;”这行的前面):
  2. define('WP_POST_REVISIONS', false);
    define('AUTOSAVE_INTERVAL', false);
    
  3. 找到并打开%WP%/wp-admin/post-new.php 和%WP%/wp-admin/post.php 这两个文件,将其 “wp_enqueue_script(‘autosave’);” 注释或删除掉。如下:
  4. //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');

 

参考资料

  1. WordPress 3.4.1关闭自动草稿、自动保存和禁用文章修订版
  2. WordPress 3.4.2、3.5文章ID连续方法—禁用自动草稿、自动保存和文章修订
  3. wordpress插件清理自动保存多版本草稿及关闭方法
  4. Delete-Revision插件


作 者: D瓜哥,https://www.diguage.com/
原文链接:https://wordpress.diguage.com/archives/5.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

  1. 2013年4月2日19:18 | #1

    太麻烦了,懒得弄了

  2. 2013年4月7日11:40 | #2

    @常青 可以考虑使用Delete-Revision插件,偶尔删除一下就可以了。对于使用wordpress默认编辑器写文章的朋友,建议不要关闭自动保存

    • D瓜哥
      2013年4月7日11:47 | #3

      我不想装插件了,所以就自己吓倒腾了。哈哈

  3. 2013年4月10日16:45 | #4

    确认非常之麻烦。一般人也就是写个博客而已,最多注意下排版就了不得了。

  4. 归来
    2013年5月2日18:57 | #5

    这个不错,这样的话,以后首页文章的排序就可以按照ID的奇偶数设置不同的样式了

  5. 2014年6月19日16:21 | #6

    对于空余id的利用很重要,能不能写个function语言,简化操作困难度。

  6. 2014年7月3日22:52 | #7

    最新的版本用这个不行。

  7. 2015年5月8日18:32 | #9

    我不是沙发,但我顶楼主!

  8. 2019年3月25日23:31 | #10

    感谢,刚才试了,只不过最新版WP似乎有点问题。

  1. 本文目前尚无任何 trackbacks 和 pingbacks.