
本文介绍如何将原始按日期分组的宾客数组,重构为“房间→日期→行号”三级嵌套结构,并据此生成符合多客/多日/多房需求的html日程表,解决同房间同日多人占用时的行列对齐问题。
本文介绍如何将原始按日期分组的宾客数组,重构为“房间→日期→行号”三级嵌套结构,并据此生成符合多客/多日/多房需求的html日程表,解决同房间同日多人占用时的行列对齐问题。
在酒店或民宿管理系统中,常需将宾客入住信息按「房间 × 周几」维度可视化呈现为表格(如7列代表周一至周日,每行代表某房间的某一床位)。但原始数据通常以日期为第一级键(如 $calendar['Monday, 2022-08-01']),且同一日期下可能有多个宾客入住同一房间——这导致直接遍历难以精准映射到表格的「房间行 × 日期列 × 床位序号」三维坐标。
核心思路是数据结构重塑(Data Reshaping):不再以日期为根,而是以房间为顶层分组,再按日期、再按床位序号(即该房间当日第几个入住者)逐层嵌套。这样,渲染表格时只需两层循环:外层遍历房间及容量,内层遍历日期;每个单元格通过三重键(房间号 + 日期 + 行索引)快速查表,天然支持“Room100 周三 第2位住客”这类定位。
以下是完整实现步骤:
1. 重构数据:从「日期→宾客」转为「房间→日期→行索引→宾客」
$calendarByRoom = [];
foreach ($calendar as $day => $guests) {
foreach ($guests as $guest) {
$room = $guest['Room'];
// 确保房间和日期键存在
if (!isset($calendarByRoom[$room][$day])) {
$calendarByRoom[$room][$day] = [];
}
// 按顺序追加,索引即为该房间当日的床位序号(0-based)
$calendarByRoom[$room][$day][] = $guest;
}
}
// 此时 $calendarByRoom['100']['Wednesday, 2022-08-03'] = [ [...Anna...], [...Peter...] ]
2. 渲染表格:按房间容量展开行,按日期展开列
echo '
| '; // 空首列 foreach ($daynames as $day) { echo " | $day | "; } echo 'Room{$roomNumber} | "; // 遍历每一天,查找该房间当日第 $rowIndex 位宾客 foreach ($daynames as $day) { $name = '------'; if ( isset($calendarByRoom[$roomNumber][$day][$rowIndex]) && isset($calendarByRoom[$roomNumber][$day][$rowIndex]['Firstname']) ) { $name = htmlspecialchars($calendarByRoom[$roomNumber][$day][$rowIndex]['Firstname']); } echo "$name | "; } echo ''; } } echo '
|---|
关键注意事项:
-
数据一致性校验:示例中
Martina和Janni被错误分配至Room100,实际应归属Room200。务必确保原始$calendar中Room字段值与$roomnrarray的roomnumber严格一致(建议统一用整型或去前导零)。 -
空单元格处理:使用
'------'作为占位符,生产环境可替换为<span class="free">空闲</span>并添加 CSS 样式。 -
安全输出:对宾客姓名使用
htmlspecialchars()防止 XSS,尤其当数据来自用户输入时。 -
扩展性提示:若需支持“同一房间跨日连续入住”,当前结构仍适用——只需保证
$calendar中每个入住记录独立存在,重塑逻辑会自动归集到对应房间+日期+序号。
此方案摒弃了易出错的计数器状态机(如原代码中的 $wdh, $wdhcount),转而依赖清晰的数据结构和确定性索引访问,大幅提升可读性、可维护性与健壮性。











