如何在 php table 中按属性对齐 MSSQL 数据
结论
要让订单号、付款状态和订单状态一一对应,应在一次查询中取出这三个字段,并在同一个遍历循环里为每条订单生成一个 <tr>。
不要用三个独立循环分别输出订单号、付款状态和订单状态。这样既难以保证三组数据始终属于同一订单,也会让内容落在不同的表格位置。
正确的表格结构
HTML 表格应保持下面的层级:
<table>
<thead>
<tr>
<th>ORDER NUMBER</th>
<th>PAYMENT STATUS</th>
<th>ORDER STATUS</th>
</tr>
</thead>
<tbody>
<tr>
<td>订单号</td>
<td>付款状态</td>
<td>订单状态</td>
</tr>
</tbody>
</table>
每查到一条订单记录,就输出一个完整的 <tr>,再将该记录的三个属性分别放入三个 <td>。
使用 sqlsrv 的完整示例
假设数据库表名是 orders,包含以下字段:
order_numberpayment_statusorder_status
代码可以写成:
<?php
$sql = "
SELECT order_number, payment_status, order_status
FROM orders
ORDER BY order_number
";
$stmt = sqlsrv_query($conn, $sql);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
$paymentStatusLabels = [
0 => 'En attente paiement',
1 => 'Commande payée',
];
$orderStatusLabels = [
0 => 'Commande en attente',
1 => 'Commande en cours de préparation',
];
?>
<table class="orders-table">
<thead>
<tr>
<th>NUMERO COMMANDE</th>
<th>STATUT PAIEMENT</th>
<th>STATUT COMMANDE</th>
</tr>
</thead>
<tbody>
<?php while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)): ?>
<?php
$paymentStatus = $paymentStatusLabels[$row['payment_status']]
?? 'Statut de paiement inconnu';
$orderStatus = $orderStatusLabels[$row['order_status']]
?? 'Statut de commande inconnu';
?>
<tr>
<td>
<?= htmlspecialchars(
(string) $row['order_number'],
ENT_QUOTES,
'UTF-8'
) ?>
</td>
<td>
<?= htmlspecialchars($paymentStatus, ENT_QUOTES, 'UTF-8') ?>
</td>
<td>
<?= htmlspecialchars($orderStatus, ENT_QUOTES, 'UTF-8') ?>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
<?php sqlsrv_free_stmt($stmt); ?>
这里真正决定数据能否对齐的,不是使用 switch 还是状态文本数组,而是三个单元格都在同一个 while 循环、同一个 <tr> 中生成。这样,每一行都会对应一条订单记录。
继续使用 switch 的写法
如果状态值较多,或者现有代码已经用了 switch,也可以继续保留:
<?php while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)): ?>
<tr>
<td>
<?= htmlspecialchars(
(string) $row['order_number'],
ENT_QUOTES,
'UTF-8'
) ?>
</td>
<td>
<?php
switch ((int) $row['payment_status']) {
case 0:
echo 'En attente paiement';
break;
case 1:
echo 'Commande payée';
break;
default:
echo 'Statut de paiement inconnu';
}
?>
</td>
<td>
<?php
switch ((int) $row['order_status']) {
case 0:
echo 'Commande en attente';
break;
case 1:
echo 'Commande en cours de préparation';
break;
default:
echo 'Statut de commande inconnu';
}
?>
</td>
</tr>
<?php endwhile; ?>
相比状态数组,switch 的代码会长一些,但不会影响数据对齐。只要所有字段都在同一次遍历中输出即可。
添加基础样式
表格结构正确后,可以用 CSS 调整对齐方式和间距:
.orders-table {
width: 100%;
border-collapse: collapse;
}
.orders-table th,
.orders-table td {
padding: 10px 12px;
border: 1px solid #ccc;
text-align: left;
vertical-align: middle;
}
.orders-table th {
background-color: #f5f5f5;
}
.orders-table tbody tr:nth-child(even) {
background-color: #fafafa;
}
如果订单号需要居中,可以单独设置第一列:
.orders-table th:first-child,
.orders-table td:first-child {
text-align: center;
}
常见错误
分别查询或遍历三个字段
下面这种处理方式不合适:
// 第一次循环输出所有订单号
// 第二次循环输出所有付款状态
// 第三次循环输出所有订单状态
即使三次查询目前返回的记录数相同,也不能仅凭记录位置判断它们属于同一订单。一旦数据发生新增、删除或排序变化,对应关系就可能错乱。
在 <tr> 外输出 <td>
<td> 必须写在 <tr> 内。浏览器有时会尝试修复不正确的 HTML,但修复后的显示结果并不可靠。
正确结构如下:
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
查询时没有明确排序
如果页面需要按订单号、创建时间或其他字段展示数据,应在 SQL 中明确添加 ORDER BY:
ORDER BY order_number
不要依赖数据库的默认返回顺序。没有指定 ORDER BY 时,记录顺序无法保证。
直接输出数据库内容
订单号等数据库内容应先通过 htmlspecialchars() 转义,以免特殊字符破坏 HTML,同时降低跨站脚本攻击风险:
echo htmlspecialchars(
(string) $row['order_number'],
ENT_QUOTES,
'UTF-8'
);
如果实际字段名与示例不同,请将 order_number、payment_status 和 order_status 替换成查询结果中的真实字段名。处理方式仍然相同:一条数据库记录对应一个 <tr>,该记录的每个属性分别放入一个 <td>。
备注:内容仅供参考。
