
本文详解如何在 PHP 中安全、结构化地将用户订单数据动态嵌入 HTML 表格,并完整集成到邮件正文变量中,避免常见嵌套错误与 XSS 风险,适用于发票邮件等生产场景。
本文详解如何在 PHP 中安全、结构化地将用户订单数据动态嵌入 HTML 表格,并完整集成到邮件正文变量中,避免常见嵌套错误与 XSS 风险,适用于发票邮件等生产场景。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
在构建电商类邮件模板(如订单发票)时,一个典型需求是:将客户基本信息与多条订单明细统一渲染进单个语义化 推荐采用「数据采集 → HTML 构建」两阶段模式,既保障安全性,又提升可读性与可维护性: 生成的 $emailbody 是一个完整、合法、单 中,并最终赋值给 $emailbody 变量用于发送。您当前代码的核心问题在于:
✅ 已正确查询出订单数据($sql = mysqli_query(...)),但未将其结构化收集;
❌ 将 循环逻辑写在了 $emailbody 字符串拼接之外,导致无法动态注入; 缺少对应
❌ 直接拼接未过滤的数据库字段(如 $row['item']),存在 XSS 安全隐患;
❌ 表格结构不闭合(Total
开始标签)。
✅ 正确方案:先收集数据,再模板化拼接
<?php
// 1. 数据采集阶段:安全获取并转义所有订单项
$orders = [];
$sql = mysqli_query($con, "SELECT item, quantity, price, subtotal FROM orders WHERE invoice='$invoice'");
if ($sql && mysqli_num_rows($sql) > 0) {
while ($row = mysqli_fetch_assoc($sql)) {
$orders[] = [
'item' => htmlspecialchars($row['item'], ENT_QUOTES, 'UTF-8'),
'quantity' => (int)$row['quantity'],
'price' => number_format((float)$row['price'], 2),
'subtotal' => number_format((float)$row['subtotal'], 2)
];
}
}
// 2. HTML 构建阶段:在字符串中内联 PHP 循环(使用 heredoc 或字符串拼接)
$emailbody = <<<EOD
<table style="margin:10px auto; border-collapse: collapse; border: 1px solid black; padding-left:10px;">
<tr>
<th colspan="4" style="border: 1px solid black; padding: 6px 10px; background-color: #00000061; color: white; font-weight:400;">
<h4>Invoice Order No. # {$invoice}</h4>
</th>
</tr>
<tr>
<td colspan="4" style="text-align:left; border: 1px solid #ddd; padding: 5px 20px;">
<p style="text-align:right; line-height: 1.2; padding:5px 15px;">{$name}</p>
<p style="text-align:right; padding:5px 15px;">{$address}</p>
<p style="text-align:right; line-height: 1.2; padding:5px 15px;">{$phone}</p>
<p style="text-align:right; line-height: 1.2; padding:5px 15px;">{$email}</p>
<p style="text-align:left; line-height: 1.2; padding:5px 15px;">Invoice Date: {$date}</p>
</td>
</tr>
<tr style="background-color: #00000061; color: white; font-weight:400;">
<th style="border: 0; padding: 8px 10px;">ITEM</th>
<th style="border: 0; padding: 8px 10px;">QUANTITY</th>
<th style="border: 0; padding: 8px 10px;">PRICE (USD)</th>
<th style="border: 0; padding: 8px 10px;">TOTAL</th>
</tr>
EOD;
// 3. 动态插入订单行(关键:在字符串中拼接循环结果)
foreach ($orders as $order) {
$emailbody .= <<<EOD
<tr>
<td style="border: 0; padding: 6px 10px;">{$order['item']}</td>
<td style="border: 0; padding: 6px 10px; text-align:center;">{$order['quantity']}</td>
<td style="border: 0; padding: 6px 10px; text-align:right;">\${$order['price']}</td>
<td style="border: 0; padding: 6px 10px; text-align:right;">\${$order['subtotal']}</td>
</tr>
EOD;
}
// 4. 添加总计行(修复原结构:补全<tr>标签)
$emailbody .= <<<EOD
<tr>
<td colspan="4" style="background-color:#0a0512a8; color:white; text-align: center; padding:10px 25px;">
<strong>Total: \$ {$carttotal}</strong>
</td>
</tr>
</table>
EOD;
?>⚠️ 关键注意事项
,表格仍保持结构完整——这是比 while() 更健壮的写法。
✅ 最终效果
结构的 HTML 字符串,可直接传入 PHPMailer 或 mail() 函数发送,且所有用户输入均已转义,兼顾安全性、可读性与跨客户端兼容性。


















