
本文介绍一种健壮的 php 表单处理模式:当用户提交失败时自动保留已填内容便于修正;提交成功后重定向至带提示参数的页面,既清空表单又避免重复提交,同时确保“邮件已发送”消息可靠显示。
在构建联系表单时,良好的用户体验要求:出错时保留用户输入(避免重复填写),成功后清空表单并明确反馈结果。直接在 $_POST 中 unset() 或依赖页面刷新无法兼顾两者——因为 $_POST 数据仅存在于当前请求生命周期,且未重定向会导致 F5 刷新重复提交。
✅ 正确做法是采用 POST-Redirect-GET(PRG)模式:
- 接收 POST 请求 → 验证并发送邮件
- 若成功 → 用 header('Location: contact.php?sent') 重定向到自身带查询参数的 GET 请求
- 在 GET 请求中显示成功提示,并渲染一个全新、干净的表单
以下是完整、安全、可扩展的 contact.php 示例(已移除硬编码邮箱,增强可读性):
<?php
$error = '';
$sent = false;
// 检查是否为成功提交后的 GET 请求(即 ?sent 存在)
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['sent'])) {
$sent = true;
}
// 处理表单提交(POST)
elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 基础验证(生产环境应使用更严格的过滤,如 filter_input())
$name = trim($_POST['name'] ?? '');
$email = filter_var($_POST['email'] ?? '', FILTER_SANITIZE_EMAIL);
$msg = trim($_POST['msg'] ?? '');
if (empty($name) || empty($email) || empty($msg)) {
$error = '请填写所有必填字段。';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = '请输入有效的邮箱地址。';
} else {
// 构建邮件头防止注入(关键!)
$headers = "From: {$name} <{$email}>\r\n" .
"Reply-To: {$email}\r\n" .
"X-Mailer: PHP/" . phpversion();
// 发送邮件(建议改用 PHPMailer 或 SMTP 提升可靠性)
if (mail('your@example.com', '网站联系表单', $msg, $headers)) {
header('Location: contact.php?sent');
exit;
} else {
$error = '邮件发送失败,请稍后重试。';
}
}
}
?>
<!-- 成功提示(仅在 ?sent 时显示) -->
<?php if ($sent): ?>
<p id="output-area" style="color:green;font-weight:bold;">✅ 您的邮件已成功发送!</p>
<?php endif; ?>
<!-- 错误提示 -->
<?php if ($error): ?>
<p class="error" style="color:#d32f2f;background:#ffebee;padding:8px;border-radius:4px;">⚠️ <?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>
<!-- 表单:value 和 textarea 内容均基于 $_POST 回显(仅 POST 提交后保留) -->
<form class="contact-form" action="contact.php" method="post">
<label>姓名:<input type="text" name="name" value="<?php echo htmlspecialchars($name ?? ''); ?>" required></label><br><br>
<label>邮箱:<input type="email" name="email" value="<?php echo htmlspecialchars($email ?? ''); ?>" required></label><br><br>
<label>留言:<textarea name="msg" rows="5" required><?php echo htmlspecialchars($msg ?? ''); ?></textarea></label><br><br>
<input type="submit" value="发送消息">
</form>? 关键要点说明:
立即学习“PHP免费学习笔记(深入)”;
- ✅ header('Location: ...') + exit 是核心:强制跳转后,浏览器发起新 GET 请求,$_POST 彻底失效,表单自然清空;
- ✅ htmlspecialchars() 必须调用:防止 XSS 攻击,尤其回显用户输入时;
- ✅ filter_var() 过滤邮箱:比简单 trim() 更安全;
- ✅ 邮件头防御:手动构造 From 和 Reply-To 时需严格校验,避免邮件头注入;
- ⚠️ mail() 函数局限性:开发阶段可用,上线建议切换至 PHPMailer 或 SMTP 服务(如 SendGrid),以保障送达率与错误追踪能力。
通过该方案,用户再也不会遇到“发完邮件还留着旧数据”或“刷新后提示消失”的问题——它兼顾了健壮性、安全性与用户体验。











