You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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循环直接跳过,导致后面的事件完全没机会渲染。
  • 事件匹配逻辑倒置:原本应该先遍历所有时段,再在每个时段里查找是否有对应事件;现在是遍历每个事件,再生成所有时段,重复生成表格还导致事件匹配混乱。

修复步骤

  1. 预处理事件数组:先把所有数据库事件转换成日期时间字符串 => 事件内容的关联数组,方便后续快速匹配。
  2. 重构循环逻辑:先初始化$hour,然后循环每个小时生成表格行,在每个日期列里检查是否有对应事件。
  3. 日期格式统一:确保事件的日期格式和表格中生成的$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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 21:10:28