WordPress中基于Formidable表单条目数实现页面重定向的问题
问题核心原因
两个故障都和全局变量写法无关,是WordPress钩子执行顺序、HTTP头发送时机不对导致的:
- 你挂载在
template_redirect上的重定向函数,执行时间比挂载在frm_display_form_action上的计数函数早。重定向逻辑运行时计数逻辑还没执行,全局$count自然是NULL frm_display_form_action触发时,页面的HTTP响应头已经输出完成,这时候调用wp_redirect()根本发不出跳转指令,重定向必然失效
最优实现方案(无全局变量、无执行顺序坑)
直接把表单提交计数逻辑整合到重定向函数里,不需要跨函数传值,逻辑闭环不会出现时序问题,代码如下:
// 保留原有表单提交次数限制逻辑 add_action('frm_display_form_action', 'check_entry_countt', 8, 3); function check_entry_countt($params, $fields, $form){ $current_user = wp_get_current_user(); remove_filter('frm_continue_to_new', '__return_false', 50); if( $form->id == 4 && !is_admin() && user_can( $current_user, "booknetic_staff" ) ){ $entry_count = FrmEntry::getRecordCount("form_id=". $form->id ." AND user_id=".get_current_user_id()); if($entry_count >= 1){ echo 'You have already submitted your data. Please visit your profile/account if you want to update'; add_filter('frm_continue_to_new', '__return_false', 50); } } } // 重定向逻辑独立判断,不依赖全局变量 add_action( 'template_redirect', 'my_logged_in_redirect' ); function my_logged_in_redirect() { if ( !is_user_logged_in() ) { return; } $current_user = wp_get_current_user(); // 非目标角色直接跳过判断 if ( !user_can( $current_user, "booknetic_staff" ) ) { return; } // 在重定向触发时机直接查询提交次数,不存在时序问题 $entry_count = FrmEntry::getRecordCount("form_id=4 AND user_id=".get_current_user_id()); // 满足 提交数为0+在指定页面 条件时跳转 if ( $entry_count == 0 && (is_front_page() || is_page('profile') || is_page('account')) ) { wp_redirect( home_url('/first-time-application-temp/') ); exit; } }
全局变量传值适配方案
如果不想重复写查询逻辑,必须使用全局$count传值,需要把计数逻辑的执行时机提前到template_redirect之前,不能挂载在frm_display_form_action上做计数,修改代码如下:
// 提前在init钩子计算count值,保证后续所有钩子都能正常读取全局变量 add_action( 'init', 'pre_check_user_entry_count' ); function pre_check_user_entry_count() { global $count, $user_ID; if ( !is_user_logged_in() || is_admin() ) { $count = null; return; } $current_user = wp_get_current_user(); if ( user_can( $current_user, "booknetic_staff" ) ) { $count = FrmEntry::getRecordCount("form_id=4 AND user_id=".$user_ID); } else { $count = null; } } // 表单限制逻辑直接读取全局count即可 add_action('frm_display_form_action', 'check_entry_countt', 8, 3); function check_entry_countt($params, $fields, $form){ global $count; $current_user = wp_get_current_user(); remove_filter('frm_continue_to_new', '__return_false', 50); if( $form->id == 4 && !is_admin() && user_can( $current_user, "booknetic_staff" ) ){ if($count >= 1){ echo 'You have already submitted your data. Please visit your profile/account if you want to update'; add_filter('frm_continue_to_new', '__return_false', 50); } } } // 重定向函数直接读取全局count做判断 add_action( 'template_redirect', 'my_logged_in_redirect' ); function my_logged_in_redirect() { global $count; if ( is_user_logged_in() && $count === 0 && (is_front_page() || is_page('profile') || is_page('account')) ) { wp_redirect( home_url('/first-time-application-temp/') ); exit; } }
注意:永远不要在
frm_display_form_action及更晚执行的钩子内直接调用wp_redirect(),这类钩子触发时HTTP响应头已经输出,必然导致跳转失败,所有重定向逻辑必须放在template_redirect及更早执行的钩子中运行。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

