PAYATHON 2026

如何在 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_number
  • payment_status
  • order_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>。

备注:内容仅供参考。