PHP日历开发问题:仅首个事件显示,其余事件丢失
问题
开发简易日历,想用数据库中的事件替换对应时段,但只有第一个事件能显示,其余事件都无法展示。用fetch_all获取数据后,循环转换日期格式匹配表格日期,循环后var_dump能看到所有元素,但if条件判断里只有首个事件生效。
尝试调整循环后,var_dump得到的数组里,第一个元素包含首个日期,第二个包含前两个日期,第三个包含全部三个日期,但索引都是0。有人建议用DateTime替代date/strtotime,但觉得使用难度高。
原代码:
<tbody> <?php for ($b = 0; isset($row[$b]); $b++) { $event = date('d M Y H:i', strtotime($row[$b][1])); while ($hour <= 19) { echo "<tr>"; for ($j = 0; $j <= 0; $j++) { $time1 = $hour . ":00"; echo "<td>" . $time1 . "</td>"; } for ($k = 0; isset($five_days[$k]); $k++) { $date_match = $five_days[$k].' '.$time1; if ($date_match === $event) { echo "<td>" . $row[$b][0]."</td>"; } else { echo "<td>" . $time1 . "</td>"; } } for ($j = 5; $j <= 6; $j++) { echo "<td>" . "Indisponible" . "</td>"; } echo "</tr>"; $hour++; } } ?> </tbody>
解决方案
核心问题分析
- 循环嵌套逻辑错误:外层
for($b...)循环里嵌套了while($hour <=19),第一次处理第一个事件时,$hour会从初始值一直递增到20,后续处理第2、3个事件时,$hour已经大于19,while循环直接跳过,导致后面的事件完全没机会渲染。 - 事件匹配逻辑倒置:原本应该先遍历所有时段,再在每个时段里查找是否有对应事件;现在是遍历每个事件,再生成所有时段,重复生成表格还导致事件匹配混乱。
修复步骤
- 预处理事件数组:先把所有数据库事件转换成
日期时间字符串 => 事件内容的关联数组,方便后续快速匹配。 - 重构循环逻辑:先初始化
$hour,然后循环每个小时生成表格行,在每个日期列里检查是否有对应事件。 - 日期格式统一:确保事件的日期格式和表格中生成的
$date_match格式完全一致,避免匹配失败。
修改后的代码
<tbody> <?php // 预处理事件:把事件转成 [格式化后的日期时间 => 事件内容] 的数组 $event_map = []; foreach ($row as $item) { // 确保这里的格式和后面$date_match的格式完全一致 $event_time = date('d M Y H:i', strtotime($item[1])); $event_map[$event_time] = $item[0]; } // 初始化小时,从需要的起始值开始(示例为8点) $hour = 8; while ($hour <= 19) { echo "<tr>"; // 显示当前小时 $time1 = $hour . ":00"; echo "<td>" . $time1 . "</td>"; // 遍历五天的日期,匹配事件 foreach ($five_days as $day) { $date_match = $day . ' ' . $time1; // 检查当前日期时间是否有事件 if (isset($event_map[$date_match])) { echo "<td>" . $event_map[$date_match] . "</td>"; } else { echo "<td>" . $time1 . "</td>"; } } // 显示不可用的列 for ($j = 5; $j <= 6; $j++) { echo "<td>Indisponible</td>"; } echo "</tr>"; $hour++; } ?> </tbody>
额外说明
- 如果
$row数组索引都是0,检查fetch_all的参数:用MYSQLI_ASSOC会返回关联数组,MYSQLI_NUM是数字索引,确认数据库查询返回的字段顺序是否正确。 - 若遇到日期格式兼容问题,
DateTime其实可以更精准解析日期,比如:$dt = DateTime::createFromFormat('Y-m-d H:i:s', $item[1]); $event_time = $dt->format('d M Y H:i');
内容的提问来源于stack exchange,提问作者R4DION
相关产品推荐
相关产品推荐

