WP Boilerplate公共区域表单提交重定向出现headers already sent错误求助
问题原因
- 核心错误是重定向逻辑执行时机太晚:
wp_redirect()必须在任何输出发送到浏览器之前调用,你将重定向调用放在了public\partials\filename.php这个前端模板文件中,模板文件加载时已经开始输出页面内容,导致HTTP头已经发送完成,无法再修改重定向头。 - 额外触发输出的代码:你在调用重定向之前执行了
echo 'code already used'、print_r('code not valid'),这些输出会先被发送到浏览器,直接触发headers already sent错误。 - 钩子未正确使用:你已经注册了
wp_loaded钩子来触发重定向方法,但实际却在模板文件中直接调用redirect_to_dashboard,注册的钩子完全没有生效,反而在输出阶段执行了重定向逻辑。 - 小概率原因:模板文件PHP标签外存在多余的空格、换行,也会导致提前输出。
修复方案
- 把所有表单提交、数据库操作、重定向逻辑全部从模板文件中移除,放到公共类的方法中,模板文件只负责渲染页面内容和表单。
- 直接利用已经注册的
wp_loaded钩子处理所有提交逻辑,这个钩子执行时WordPress还未输出任何内容,完全满足重定向的要求。 - 移除所有重定向执行前的调试输出(echo、print_r等),如果需要给用户提示,将错误状态通过URL参数携带,跳转后在目标页读取参数显示提示。
修正后的代码示例
公共类中的重定向&业务处理方法
public function redirect_to_dashboard() { // 非POST请求/无code参数直接跳过 if ( empty( $_POST ) || ! isset( $_POST['code'] ) ) { return; } global $wpdb; $code = sanitize_text_field( $_POST['code'] ); $result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}teptickets WHERE code = %s", $code ) ); if ( empty( $result ) ) { // 错误状态通过URL参数传递 $redirect = add_query_arg( 'error', 'invalid_code', get_permalink() ); wp_redirect( $redirect ); exit; } if ( $result->used ) { $escape_room_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tepescapes WHERE id = %d", $result->escape_room ) ); if ( $escape_room_data ) { $redirect = add_query_arg( 'error', 'code_used', get_permalink( $escape_room_data->id ) ); wp_redirect( $redirect ); exit; } } else { // 标记核销成功 $wpdb->update( "{$wpdb->prefix}teptickets", [ 'used' => 1 ], [ 'id' => $result->id ] ); // 成功状态跳转,替换为实际成功页ID即可 $redirect = add_query_arg( 'status', 'verify_success', get_permalink( 123 ) ); wp_redirect( $redirect ); exit; } }
保留原钩子注册逻辑
$this->loader->add_action( 'wp_loaded', $plugin_public, 'redirect_to_dashboard' );
模板文件中仅保留提示渲染逻辑
// 读取URL参数显示对应提示 if ( isset( $_GET['error'] ) && $_GET['error'] === 'code_used' ) { echo 'code already used'; } if ( isset( $_GET['error'] ) && $_GET['error'] === 'invalid_code' ) { echo 'code not valid'; } if ( isset( $_GET['status'] ) && $_GET['status'] === 'verify_success' ) { echo '核销成功'; } // 下方放表单渲染代码即可
内容的提问来源于stack exchange,提问作者MrY
相关产品推荐
相关产品推荐

