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

PHP发送邮件后调用header重定向页面失效问题求助

问题:PHP执行邮件发送逻辑后页面重定向失效

已尝试通用PHP重定向方案、部分JavaScript重定向方案均未生效,相关代码片段如下:

function redirect($url) {
ob_start();
header('Location: '.$url);
ob_end_flush();
exit();
}

if ( isset($_REQUEST['sendemail']) ) {
header("Content-Type: text/plain");
header("X-Node: $hostname");
$from = $_REQUEST['from'];
$name = $_REQUEST['name'];
$toemail = "djsuson@gmail.com";
$subject = "Customer question";
$message = $_REQUEST['message'];

ob_start(); //start capturing output buffer because we want to change output to html

$mail = new PHPMailer;

$mail->SMTPDebug = 2;
$mail->IsSMTP();
if ( strpos($hostname, 'cpnl') === FALSE ) //if not cPanel
    $mail->Host = 'relay-hosting.secureserver.net';
else
    $mail->Host = 'localhost';
$mail->SMTPAuth = false;

$mail->From = $from;
$mail->FromName = $name;
$mail->AddAddress($toemail);

$mail->Subject = $subject;
$mail->Body = $message;

$mailresult = $mail->Send();
$mailconversation = nl2br(htmlspecialchars(ob_get_clean()));
if ( !$mailresult ) {
    echo 'FAIL: ' . $mail->ErrorInfo . '<br />' . $mailconversation;
    redirect('http://otterlywoods.com/failure.html');
} else {
    echo $mailconversation;
    redirect('http://otterlywoods.com/success.html');
}
失效原因
  • 重定向头发送时机不符合HTTP规范:所有响应头必须在响应正文传输前发送,代码调用redirect()之前已经通过echo输出了报错信息、SMTP调试内容,此时响应头已经随正文一起发送给客户端,后续再调用header()设置Location头不会产生任何效果。
  • 自定义redirect函数逻辑错误:函数内部临时开启ob_start()无法拦截函数调用前已经输出的内容,且ob_end_flush()会直接输出缓冲内的内容,完全违背重定向"仅返回跳转头、不返回响应正文"的要求。
  • 代码逻辑顺序混乱:输出缓冲直到邮件处理逻辑段才开启,无法拦截之前已经输出的响应头之外的隐形输出(比如文件BOM头、PHP标签外的空行);开启SMTP调试模式后,调试信息被捕获后没有做持久化存储,反而直接echo输出,进一步触发了正文提前发送的问题。
修复方案
  • 修正redirect函数逻辑,重定向前清空所有已生成的输出,避免残留内容影响响应头发送:
function redirect($url) {
    // 逐层清空所有已存在的输出缓冲
    while (ob_get_level() > 0) {
        ob_end_clean();
    }
    // 强制设置302跳转头,替换之前可能存在的同名头
    header('Location: ' . $url, true, 302);
    exit;
}
  • 调整代码执行顺序
    • 把ob_start()放到整个PHP脚本的最开头,在所有业务逻辑执行前就开启输出缓冲,从入口处拦截所有意外输出。
    • 生产环境直接关闭SMTP调试:将$mail->SMTPDebug = 2;修改为$mail->SMTPDebug = 0;,从根源上避免调试信息输出。如果需要留存调试日志,把$mailconversation内容存入Session或者写入本地日志文件,不要直接echo到响应中。
    • 删除重定向前的所有echo语句,不要在跳转前输出任何正文内容。
  • 排查隐形输出问题
    检查PHP文件编码是否为无BOM的UTF-8格式,确认文件开头<?php标签前没有多余空格、换行,文件末尾不要加?>标签,避免标签后多余空行被当作正文输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:15:31