You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress save_post钩子致内容重复,需实现首次发布仅修改一次

WordPress文章内容重复问题修复方案

问题根源

你的代码出现内容重复,核心原因是:

  1. save_post 钩子会在 wp_update_post 执行时再次触发,即便临时移除钩子,仍存在重复执行的逻辑漏洞;
  2. 用 get_post() 获取的是数据库中已存储的内容,而非用户提交的原始内容,二次处理时容易导致内容叠加;
  3. 强制设置 post_status = 'publish' 会干扰WordPress默认发布流程,触发额外的钩子回调。

优化方案(推荐用wp_insert_post_data过滤器)

之前用这个过滤器崩溃大概率是写法错误,它是在内容存入数据库前修改数据,不会触发二次更新,更适配你的需求:

add_filter('wp_insert_post_data', 'my_modify_post_data', 10, 2);
function my_modify_post_data($data, $postarr) {
    // 只处理文章类型,排除修订版、自动草稿
    if ($data['post_type'] !== 'post' || $data['post_status'] === 'auto-draft' || isset($postarr['ID']) && wp_is_post_revision($postarr['ID'])) {
        return $data;
    }

    // 判断是否为首次发布:新增文章 或 从未发布过的文章转为发布状态
    $is_first_publish = empty($postarr['ID']) || (get_post_status($postarr['ID']) !== 'publish' && $data['post_status'] === 'publish');
    
    // 检查是否已经处理过,避免重复操作
    if ($is_first_publish && !get_post_meta($postarr['ID'] ?? 0, 'check_post_style', true)) {
        $myweb_settings = get_option('your_settings_option_name'); // 替换为你的设置选项名
        $add_extra_tag = $myweb_settings['myoption_set'] ?? '';
        $post_checked = get_post_meta($postarr['ID'] ?? 0, 'my_post_meta_style', true);

        // 符合条件则处理内容
        if (($add_extra_tag === 'Yes') || $post_checked) {
            $data['post_content'] = add_simple_tags($data['post_content']);
            $data['post_title'] = add_simple_tags($data['post_title']);
            
            // 标记为已处理(新增文章需在保存后添加meta)
            if (!empty($postarr['ID'])) {
                update_post_meta($postarr['ID'], 'check_post_style', '1');
            } else {
                add_action('save_post', function($post_id) {
                    update_post_meta($post_id, 'check_post_style', '1');
                }, 20);
            }
        }
    }

    return $data;
}

若坚持使用save_post钩子,修复后的代码

add_action('save_post', 'my_modified_content');
function my_modified_content($post_id) {
    // 排除修订版、自动草稿、非文章类型
    if (wp_is_post_revision($post_id) || get_post_status($post_id) === 'auto-draft' || get_post_type($post_id) !== 'post') {
        return;
    }

    // 验证请求合法性
    if (!check_admin_referer('update-post_' . $post_id, '_wpnonce')) {
        return;
    }

    // 检查是否已处理过
    $alreadydone = get_post_meta($post_id, 'check_post_style', true);
    if ($alreadydone === '1') {
        return;
    }

    // 判断是否为首次发布:发布时间与修改时间一致
    $is_first_publish = get_post_status($post_id) === 'publish' && get_post_field('post_date_gmt', $post_id) === get_post_field('post_modified_gmt', $post_id);
    if (!$is_first_publish) {
        return;
    }

    $myweb_settings = get_option('your_settings_option_name'); // 替换为你的设置选项名
    $add_extra_tag = $myweb_settings['myoption_set'] ?? '';
    $post_checked = get_post_meta($post_id, 'my_post_meta_style', true);

    if (($add_extra_tag === 'Yes') || $post_checked) {
        // 临时移除钩子,避免wp_update_post触发重复执行
        remove_action('save_post', 'my_modified_content');
        
        // 获取用户提交的原始内容,而非数据库中的内容
        $content = add_simple_tags($_POST['post_content'] ?? get_post_field('post_content', $post_id));
        $title = add_simple_tags($_POST['post_title'] ?? get_post_field('post_title', $post_id));

        // 更新文章,不强制设置post_status,保留原有状态
        wp_update_post([
            'ID' => $post_id,
            'post_title' => $title,
            'post_content' => $content
        ]);

        // 标记为已处理
        update_post_meta($post_id, 'check_post_style', '1');

        // 重新添加钩子
        add_action('save_post', 'my_modified_content');
    }
}

关键修复点

  • 排除修订版和自动草稿,避免不必要的回调;
  • 验证请求合法性,防止恶意触发;
  • 精准判断首次发布场景,确保仅处理一次;
  • 使用用户提交的原始内容($_POST)而非数据库内容,避免重复处理;
  • 移除不必要的post_status强制设置,遵循WordPress默认流程。

内容的提问来源于stack exchange,提问作者OneNation

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:10:30