PHP创建表格行前校验值 解决服务时长价格表列错位问题
问题根源
你现有代码存在两个直接导致渲染异常的问题:
- 原始数据中同一款服务的不同时长价格被拆分为多条独立记录,直接遍历每条记录生成一行表格,会导致同个服务重复生成多行。
- 生成单元格时仅在匹配到对应时长时才输出
<td>标签,未匹配的位置不输出空单元格占位,HTML表格会自动将后续单元格向前补位,直接导致所有价格错位到第一列。
修复方案
核心逻辑分两步:先按服务维度聚合数据,再严格按表头顺序生成单元格,无对应价格时输出空单元格保证列对齐,值校验逻辑直接嵌入单元格生成环节即可。
修复后完整代码
// 预定义所有时长档位,固定顺序保证列对齐 $allSlots = ["45min", "1h", "1,5h", "2h", "2,5h", "3h"]; $groupedServices = []; $existSlots = []; // 第一步:按服务ID聚合同服务的所有时长价格,同时统计实际存在的时长列 foreach ($tableRow as $item) { $serviceId = $item['id']; if (!isset($groupedServices[$serviceId])) { $groupedServices[$serviceId] = [ 'name' => $item['name'], 'prices' => [] ]; } $groupedServices[$serviceId]['prices'][$item['slot']] = $item['price']; if (!in_array($item['slot'], $existSlots)) { $existSlots[] = $item['slot']; } } // 第二步:生成表格头部,仅展示实际存在价格的时长列 $table = '<div class="product-table-wrap product-table-responsive"> <table class="product-table"> <thead class="product-table-head"> <tr class="product-table-row"> <th class="product-table-cell category-title"><span class="product-pricing-text">'.$cat_name.'</span></th>'; foreach ($allSlots as $slot) { if (in_array($slot, $existSlots)) { $table .= '<th class="product-table-cell product-duration"><span class="product-pricing-text">'.$slot.'</span></th>'; } } $table .= '</tr> </thead> <tbody class="product-table-body">'; // 第三步:逐行生成服务数据,按表头顺序输出单元格 foreach ($groupedServices as $service) { $table .= '<tr>'; $table .= '<td class="product-table-cell category-title"><span class="product-pricing-text">'.$service['name'].'</span></td>'; foreach ($allSlots as $slot) { // 跳过表头不存在的列 if (!in_array($slot, $existSlots)) continue; if (isset($service['prices'][$slot])) { $rawPrice = trim($service['prices'][$slot]); // ---------------值校验逻辑开始--------------- $validPrice = ''; // 校验1:空值直接跳过 if (empty($rawPrice)) { $validPrice = ''; } // 校验2:匹配金额格式(支持数字、小数点/逗号分隔、可选欧元符号) elseif (preg_match('/^\d+([.,]\d{1,2})?€?$/', $rawPrice)) { // 转义特殊字符防XSS $validPrice = htmlspecialchars($rawPrice, ENT_QUOTES); } // 校验不通过时显示占位符 else { $validPrice = '-'; } // ---------------值校验逻辑结束--------------- $table .= '<td class="product-table-cell product-duration"><a href="#" class="product-pricing-text">'.$validPrice.'</a></td>'; } else { // 无对应价格输出空单元格占位,保证列不错位 $table .= '<td class="product-table-cell product-duration"></td>'; } } $table .= '</tr>'; } // 原有固定的泰式按摩行,按列数自动适配 $table .= '<tr class="product-table-row"> <td class="product-table-cell category-title"><span class="product-pricing-text">Thai massage</span></td>'; $fixedPriceMap = [ '45min' => '48,00', '1h' => '66,00', '1,5h' => '78,00', '2h' => '93,00', '2,5h' => '108,00' ]; foreach ($allSlots as $slot) { if (!in_array($slot, $existSlots)) continue; $price = $fixedPriceMap[$slot] ?? ''; $tag = $slot === '45min' ? '<a href="#"' : '<span'; $closeTag = $slot === '45min' ? '</a>' : '</span>'; $table .= '<td class="product-table-cell product-duration">'.$tag.' class="product-pricing-text">'.$price.$closeTag.'</td>'; } $table .= '</tr> </tbody> </table> </div>'; echo $table;
校验规则说明
你可以根据自己的业务需求调整校验逻辑:
- 价格格式校验:修改正则规则适配你的货币单位、小数位数要求
- 空值处理:可以设置默认显示文本,也可以留空
- 特殊字符转义:必须保留
htmlspecialchars()处理,避免用户输入恶意脚本导致XSS漏洞 - 异常值处理:校验不通过的价格可以显示
-或者添加错误样式,方便后台排查数据问题
内容的提问来源于stack exchange,提问作者zopriys
相关产品推荐
相关产品推荐

