PHP+AJAX动态表单数组为空问题修复(无MySQL,含PHPMailer)
解决动态表格AJAX传值+PHPMailer SMTP发送的问题
看起来你遇到的问题主要集中在前端表格数据获取错误和PHP JSON解码崩溃这两个核心点上,我来一步步帮你解决:
第一步:修复前端表格的ID重复问题
你当前的HTML里,动态表格的每行都用了相同的id="value1"和id="value2",这违反了HTML中ID唯一的规则——jQuery选择器只会匹配到第一个带该ID的元素,后面行的内容根本拿不到。把ID改成class即可:
<table id="dynamic_field"> <tr> <td><textarea class="form-control value1" required></textarea></td> <td><textarea class="form-control value2" required></textarea></td> </tr> <!-- 动态添加的行也用同样的class --> </table>
第二步:修正表格数据获取逻辑(用.val()替代.text())
你之前用.text()来获取textarea的值,这是错误的:.text()取的是元素标签之间的静态文本内容(比如默认的换行空格),而用户输入的内容存在表单元素的value属性里,必须用.val()获取。修改你的storeTblValues函数:
function storeTblValues(){ var TableData = []; $("#dynamic_field tr").each(function (index, tr) { // 用class选择器找每行对应的textarea,并用.trim()去掉多余空格换行 TableData.push({ "value1": $(tr).find('.value1').val().trim(), "value2": $(tr).find('.value2').val().trim() // 其他字段同理添加 }); }); return TableData; }
第三步:优化AJAX请求,避免手动JSON.stringify
手动把数组转成JSON字符串传递容易出现编码问题,导致PHP的json_decode崩溃。jQuery的AJAX可以直接接收数组,会自动编码成PHP能识别的数组格式,简化传递逻辑:
function sendEmail() { var name = $("#name").val().trim(); var email = $("#email").val().trim(); var tableData = storeTblValues(); // 先做基础验证,避免空数据提交 if (!name || !email || tableData.length === 0) { alert("请填写所有必填字段!"); return; } $.ajax({ url: 'sendEmail.php', method: 'POST', data: { name: name, email: email, TableData: tableData // 直接传数组,不用转JSON }, success: function(response) { console.log("提交成功:", response); alert("邮件发送成功!"); // 可选:重置表单 $("#name, #email").val(''); $("#dynamic_field .value1, #dynamic_field .value2").val(''); }, error: function(xhr, status, error) { console.error("提交失败:", error); alert("邮件发送失败,请稍后重试。"); } }); }
第四步:PHP端安全处理数据+PHPMailer发送
现在PHP可以直接通过$_POST['TableData']拿到数组,不用json_decode,避免了解码崩溃的问题。同时要做好数据验证和转义,防止XSS:
<?php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; require 'vendor/autoload.php'; // 确保PHPMailer的自动加载路径正确 // 验证请求方式和必填字段 if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['name'], $_POST['email'], $_POST['TableData'])) { http_response_code(400); echo json_encode(["status" => "error", "message" => "无效请求"]); exit; } // 清理和验证数据 $name = htmlspecialchars(trim($_POST['name'])); $email = trim($_POST['email']); $tableData = $_POST['TableData']; if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { http_response_code(400); echo json_encode(["status" => "error", "message" => "邮箱格式不正确"]); exit; } // 把表格数据转成HTML格式,方便邮件展示 $htmlTable = '<table border="1" cellpadding="6" cellspacing="0" style="border-collapse: collapse;">'; $htmlTable .= '<tr><th>Value 1</th><th>Value 2</th></tr>'; foreach ($tableData as $row) { $htmlTable .= '<tr>'; $htmlTable .= '<td>' . htmlspecialchars($row['value1']) . '</td>'; $htmlTable .= '<td>' . htmlspecialchars($row['value2']) . '</td>'; $htmlTable .= '</tr>'; } $htmlTable .= '</table>'; // 初始化PHPMailer发送邮件 try { $mail = new PHPMailer(true); // SMTP配置(根据你的邮箱服务商调整) $mail->isSMTP(); $mail->Host = 'smtp.example.com'; $mail->SMTPAuth = true; $mail->Username = 'your-email@example.com'; $mail->Password = 'your-smtp-password'; // Gmail需用应用专用密码 $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; // 设置收发件人 $mail->setFrom('your-email@example.com', '非营利组织名称'); $mail->addAddress('recipient@example.com'); // 接收表单数据的邮箱 $mail->addReplyTo($email, $name); // 允许回复到用户邮箱 // 邮件内容 $mail->isHTML(true); $mail->Subject = "来自 {$name} 的表单提交"; $mail->Body = <<<HTML <p><strong>姓名:</strong>{$name}</p> <p><strong>邮箱:</strong>{$email}</p> <h3>表格数据:</h3> {$htmlTable} HTML; // 纯文本备用内容 $mail->AltBody = "姓名:{$name}\n邮箱:{$email}\n\n表格数据:\n" . implode("\n", array_map(function($row) { return "Value1: {$row['value1']}, Value2: {$row['value2']}"; }, $tableData)); $mail->send(); echo json_encode(["status" => "success", "message" => "邮件发送成功"]); } catch (Exception $e) { http_response_code(500); echo json_encode(["status" => "error", "message" => "邮件发送失败:{$mail->ErrorInfo}"]); } ?>
为什么之前的代码会失败?
- 重复ID:动态行的ID重复导致jQuery无法正确定位每行的表单元素;
- .text()的错误使用:textarea的用户输入必须用
.val()获取,.text()只能拿到标签内的静态内容; - 手动JSON编码的风险:转成字符串传递容易出现编码错误,导致PHP
json_decode失败,直接传数组更可靠。
内容的提问来源于stack exchange,提问作者FreezeJunkie24
相关产品推荐
相关产品推荐

