首先需要知道页面和附件也是需要占用id的,一般这2个是可以忽略不关注的,大家更关注的是文章id连贯的问题,特别是把文章id当链接用的情况下,上下文章id相差太多,就感觉有点奇奇怪怪的,所以很多人都想解决这个问题,我很早也发过解决代码了,但是今天再测试某个东西的时候,突然想到,id缺失的问题,就尝试了一下新方法。

什么是id缺失?假如我有文章id:1、2、3、5、6、7、9,少了4和8,这就是缺失的id,但是这个4和8还在数据库里面的,只要你没有去深度清理过数据库,这个缺失的id就会一直存在数据库里面。

然后我就想到,如果新发布的文章,从缺失的id中找呢?把缺失的id重新利用发出来。

所以就在我的插件试了下:

下面这个代码就是,查找缺失的id,并把最小的id当作新文章的id,比如我有文章id:1、2、3、5、6,缺失id为4,那么新发布的文章id就是4。不过这段代码还是没有正式更新到插件里面去,插件还是用id+1的方式,因为这只是一个测试。

function wpbf_set_next_post_id() {
    global $wpdb;
    $last_post_id = (int) $wpdb->get_var("SELECT MAX(ID) FROM $wpdb->posts");
    
    if ($last_post_id > 0) {
        // 查询缺失的 ID
        $missing_ids = array();
        $all_ids = range(1, $last_post_id);
        $existing_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts");
        $missing_ids = array_diff($all_ids, $existing_ids);

        // 如果存在缺失的 ID,则将最小的缺失 ID 作为下一个文章的 ID
        if (!empty($missing_ids)) {
            $next_post_id = min($missing_ids);
        } else {
            // 如果没有缺失的 ID,则将最大的现有 ID 加 1 作为下一个文章的 ID
            $next_post_id = $last_post_id + 1;
        }

        // 设置下一个文章的 ID
        $wpdb->query("ALTER TABLE $wpdb->posts AUTO_INCREMENT = $next_post_id");
    }
}

function wpbf_disable_autosave_revisions_inconsistency() {
    if (is_admin() && isset($_POST['post_ID'])) {
        $post_id = $_POST['post_ID'];
        
        if (get_option('wpbf_disable_autosave_revisions_inconsistency') === 'on') {
            // 禁用自动保存
            wp_deregister_script('autosave');

            // 设置保留的修订版本数量为0
            add_filter('wpbf_wp_revisions_to_keep', '__return_zero');

            // 删除自动保存和修订
            global $wpdb;
            $wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'auto-draft' OR post_type = 'revision'");

            // 设置下一个文章的 ID
            wpbf_set_next_post_id();
        }
    }
}
add_action('save_post', 'wpbf_disable_autosave_revisions_inconsistency');

现在插件里面更新的代码:

function wpbf_set_next_post_id() {
    global $wpdb;
    $last_post_id = (int) $wpdb->get_var("SELECT MAX(ID) FROM $wpdb->posts");
    if ($last_post_id > 0) {
        $next_post_id = $last_post_id + 1;
        $wpdb->query("ALTER TABLE $wpdb->posts AUTO_INCREMENT = $next_post_id");
    }
}

function wpbf_disable_autosave_revisions_inconsistency() {
    if (is_admin() && isset($_POST['post_ID'])) {
        $post_id = $_POST['post_ID'];
        
        if (get_option('wpbf_disable_autosave_revisions_inconsistency') === 'on') {
            // 禁用自动保存
            wp_deregister_script('autosave');

            // 设置保留的修订版本数量为0
            add_filter('wpbf_wp_revisions_to_keep', '__return_zero');

            // 删除自动保存和修订
            global $wpdb;
            $wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'auto-draft' OR post_type = 'revision'");

            // 设置下一个文章的ID
            wpbf_set_next_post_id();
        }
    }
}
add_action('save_post', 'wpbf_disable_autosave_revisions_inconsistency');

原来实现id+1的代码是:

$wpdb->query("ALTER TABLE $wpdb->posts AUTO_INCREMENT = 1");

但是这个有一定的可能性会导致冲突,所以今天就改成了last_post_id + 1的方式。