求助:发送含表单与数据库混合数据的邮件功能异常问题
问题分析与修复方案
看起来你遇到的核心问题是PHP mail() 函数的参数顺序错误,这直接导致邮件无法正常发送。另外代码里还有几个潜在的问题,我帮你逐一梳理并修复:
核心问题:mail() 参数顺序颠倒
PHP的mail()函数正确参数顺序是:
mail(string $to, string $subject, string $message, array|string $additional_headers = [], string $additional_params = "")
你当前的代码把**消息内容($txt)和邮件头($headers)**的位置搞反了,这会导致邮件内容变成了头信息,而真正的头被当作内容发送,自然无法正常投递。
其他需要修复的问题
- 冗余循环:你的
id应该是唯一的(从room_details按id查询),所以while循环完全没必要,只会导致如果查询意外返回多行时重复发送邮件; - 未检查
$_GET['id']是否存在:如果id参数没传,mysqli_real_escape_string会报错,进而中断代码执行; - 邮件头格式不规范:缺少标准的
From头格式,也没有设置Content-Type,可能导致邮件被当作垃圾邮件或显示异常; - 缺少SQL查询错误处理:如果
mysqli_query执行失败,代码会直接跳过后续逻辑,没有任何提示; - SQL注入风险:虽然用了
mysqli_real_escape_string,但预处理语句是更安全的写法; - 跳转前的输出问题:如果后续代码有
echo输出,会导致header()跳转失效,建议加上exit()确保跳转执行。
修复后的完整代码
<?php include 'include/connect.php'; // 先检查必要参数是否存在 if (isset($_POST['book2']) && isset($_GET['id'])) { $id = mysqli_real_escape_string($conn, $_GET['id']); $sql = "SELECT room_price FROM room_details WHERE id='$id';"; $result = mysqli_query($conn, $sql); // 处理查询错误 if (!$result) { echo "数据库查询失败:" . mysqli_error($conn); exit; } if (mysqli_num_rows($result) > 0) { $row = mysqli_fetch_assoc($result); $room_price = $row['room_price']; // 提取并过滤表单数据 $email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL); $room_type = mysqli_real_escape_string($conn, $_POST['room_type']); $checkin = $_POST['checkin']; $checkout = $_POST['checkout']; $adults = (int)$_POST['adults']; $children = (int)$_POST['children']; // 验证邮箱格式 if (!$email) { echo "请输入有效的邮箱地址!"; exit; } $mailTo = "booking@johndoexxx.com"; $heading = "New Booking!"; // 规范邮件内容,加入从数据库获取的room_price $txt = "New booking received:\n" . "Room Type: " . $room_type . "\n" . "Room Price: $" . $room_price . "\n" . "Guests: " . $adults . " adults, " . $children . " children\n" . "Check-in: " . $checkin . "\n" . "Check-out: " . $checkout . "\n\n" . "Please respond to the sender at: " . $email; // 标准格式的邮件头 $headers = "From: Guest Booking <" . $email . ">\r\n" . "Reply-To: " . $email . "\r\n" . "Content-Type: text/plain; charset=UTF-8\r\n"; // 调用正确的mail函数参数顺序 if (mail($mailTo, $heading, $txt, $headers)) { header("Location: index.php?bookingsent"); exit; // 确保后续代码不执行 } else { echo "邮件发送失败,请检查服务器邮件配置!"; } } else { echo "未找到对应的房间信息!"; } } else { echo "Booking failed to process! Please check your inputs and try again."; } ?>
额外建议
- 使用专业邮件库:原生
mail()函数依赖服务器配置,容易出现投递问题,建议使用PHPMailer或SwiftMailer这类成熟的邮件库,更可靠且支持SMTP认证; - 强化表单验证:对所有用户输入的数据(比如日期格式、客人数值范围)都要做严格验证,避免无效数据进入流程;
- 改用预处理语句:把SQL查询改成预处理语句,彻底避免SQL注入风险,示例:
$stmt = $conn->prepare("SELECT room_price FROM room_details WHERE id=?"); $stmt->bind_param("i", $id); // i表示整数类型 $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc();
内容的提问来源于stack exchange,提问作者Th3710n
相关产品推荐
相关产品推荐

