WordPress postmeta字段_wpcf_belongs_artiste_id新旧值对比求助
解决WordPress postmeta字段变更检测问题
我明白你遇到的困扰了——你尝试用post_updated或save_post钩子去检测_wpcf_belongs_artiste_id这个自定义字段的新旧值,但因为钩子触发时机和数据范围的限制,始终拿不到正确的对比结果。
为什么你的原有代码行不通?
post_updated钩子里的$post_before和$post_after只包含wp_post表的基础文章数据,不包含postmeta字段。更关键的是,当这个钩子触发时,wp_postmeta表已经完成更新了,所以你直接查数据库拿到的"旧值"其实已经是新值,自然没法对比出变化。
正确的解决方案:用Meta专属钩子捕获变更
WordPress提供了专门针对postmeta更新的钩子,我们可以用pre_update_post_meta(更新前触发)直接拿到新旧值,再配合save_post的后期钩子处理邮件发送逻辑,避免更新过程中出现数据不一致的问题。
以下是优化后的完整代码:
// 在postmeta更新前捕获新旧值 add_action( 'pre_update_post_meta', 'detect_artiste_id_change', 10, 4 ); function detect_artiste_id_change( $new_value, $post_id, $meta_key, $old_value ) { // 只关注我们需要的目标字段 if ( '_wpcf_belongs_artiste_id' !== $meta_key ) { return $new_value; // 不干扰其他meta字段的更新逻辑 } // 如果字段值没有变化,直接返回 if ( $old_value === $new_value ) { return $new_value; } // 临时存储变更数据,等文章保存完成后再处理邮件 update_option( 'temp_artiste_change_data', array( 'post_id' => $post_id, 'old_artiste_id' => $old_value, 'new_artiste_id' => $new_value ) ); return $new_value; } // 在文章保存完成后发送关注用户通知邮件 add_action( 'save_post', 'send_artiste_follower_notifications', 100 ); function send_artiste_follower_notifications( $post_id ) { // 获取临时存储的变更数据 $change_data = get_option( 'temp_artiste_change_data' ); if ( empty( $change_data ) || $change_data['post_id'] !== $post_id ) { return; } // 清理临时数据,避免重复触发邮件 delete_option( 'temp_artiste_change_data' ); global $wpdb; $new_artiste_id = $change_data['new_artiste_id']; // 查询关注该艺术家的用户(用prepare防止SQL注入风险) $user_ids = $wpdb->get_results( $wpdb->prepare( "SELECT user_id FROM wp_gd_mylist WHERE item_id = %d", $new_artiste_id ) ); if ( empty( $user_ids ) ) { return; } // 遍历用户发送邮件 foreach ( $user_ids as $user_entry ) { // 用WordPress内置函数获取用户信息,更规范且兼容性更好 $user = get_user_by( 'id', $user_entry->user_id ); if ( ! $user ) { continue; } $email = $user->user_email; $subject = "Nouvelle Oeuvre sur le site!"; $message = sprintf( "Une nouvelle oeuvre de l'artiste que vous suivez %s a été mise à jour sur le site. Voici le lien : %s", $user->display_name, get_permalink( $post_id ) ); $headers = array( 'From: vosartistes.com@gmail.com' ); wp_mail( $email, $subject, $message, $headers ); } }
额外的优化建议
- 杜绝SQL注入:你的原有代码直接拼接SQL语句,存在严重安全风险,一定要用
$wpdb->prepare处理带变量的查询。 - 优先使用内置函数:比如用
get_user_by代替直接查询wp_users表,用get_post_meta代替手动查询wp_postmeta,代码兼容性和可维护性会更高。 - 避免重复查询:原有代码里重复执行了相同的meta查询,优化后只需要获取一次数据即可。
内容的提问来源于stack exchange,提问作者Mustapha Zadoussi
相关产品推荐
相关产品推荐

