如何用PHP+PDO正确展示当前及下一个广播节目?
问题:PHP广播节目列表无法正确显示当前及下一个节目
我用PHP+PDO从数据库读取所有广播节目到数组,想通过循环判断并只显示当前正在播出的节目和下一个节目,但现有代码会输出所有节目,达不到预期效果。预期输出格式为:
Current: Name Audition Title To time Next: Name Audition Title From time
相关数据说明
数组结构
ID 无需使用 name = 节目标题 Day = 星期几数字(1=周一,6=周六)
节目数组示例
Array ( [0] => Array ( [id] => 15 [0] => 15 [username] => Anna [1] => Anna [name] => Spacer w chmurach [2] => Spacer w chmurach [audition_day] => 1 [3] => 1 [start_time] => 17:12:00 [4] => 17:12:00 [end_time] => 19:12:00 [5] => 19:12:00 [canceled] => 0 [6] => 0 [audition_type] => 2 [7] => 2 ) [1] => Array ( [id] => 16 [0] => 16 [username] => Marcin [1] => Marcin [name] => Kuferek z muzyką [2] => Kuferek z muzyką [audition_day] => 1 [3] => 1 [start_time] => 20:00:00 [4] => 20:00:00 [end_time] => 22:00:00 [5] => 22:00:00 [canceled] => 0 [6] => 0 [audition_type] => 2 [7] => 2 ) [2] => Array ( [id] => 17 [0] => 17 [username] => Monika [1] => Monika [name] => test [2] => test [audition_day] => 6 [3] => 6 [start_time] => 12:25:00 [4] => 12:25:00 [end_time] => 15:25:00 [5] => 15:25:00 [canceled] => 0 [6] => 0 [audition_type] => 1 [7] => 1 ) [3] => Array ( [id] => 18 [0] => 18 [username] => Maciek [1] => Maciek [name] => test [2] => test [audition_day] => 6 [3] => 6 [start_time] => 17:20:00 [4] => 17:20:00 [end_time] => 20:20:00 [5] => 20:20:00 [canceled] => 0 [6] => 0 [audition_type] => 1 [7] => 1 ) )
现有问题代码
$audition_list = 从数据库获取的节目数组; $auditionDJ = 当前正在播出的主持人(可能是不在数据库的"AutoDJ"); $auditionTitle = 当前正在播出的节目标题; // PDO查询已在循环前执行 foreach($audition_list as &$row) { if($row["start_time"] <= $now_time) { if($row["end_time"] >= $now_time) { echo "<div class='now'>"; echo "<span>Aktualnie na antenie:</span>"; echo "<span>".$row["username"]."</span>"; echo "<span>".$row["name"]."</span>"; echo "<span>Do: ".date("H:i", strtotime($row["end_time"]))."</span>"; echo "</div>"; } else { echo "<div class='now'>"; echo "<span>Aktualnie na antenie:</span>"; echo "<span>".$auditionDJ."</span>"; echo "<span>".$auditionTitle."</span>"; echo "</div>"; } } if($row["start_time"] >= $now_time) { if($row["end_time"] <= $now_time) { echo "<div class='now'>"; echo "<span>Następnie:</span>"; echo "<span>".$auditionDJ."</span>"; echo "<span>".$auditionTitle."</span>"; echo "</div>"; } else { echo "<div class='now'>"; echo "<span>Następnie:</span>"; echo "<span>".$row["username"]."</span>"; echo "<span>".$row["name"]."</span>"; echo "<span>Od: ".date("H:i", strtotime($row["start_time"]))."</span>"; echo "</div>"; } } }
问题根源
- 遍历每个节目时都执行输出逻辑,导致所有节目被重复输出
- 未判断节目对应的星期几,会把其他日期的节目纳入判断
- 时间仅用字符串直接对比,逻辑不严谨(未处理跨天情况)
- 找到目标节目后未终止遍历,继续输出无关内容
修正后的代码
// 获取当前时间信息:星期几(1=周一,7=周日)、当前时间字符串(H:i:s) $current_day = date('N'); $current_time = date('H:i:s'); $current_show = null; $next_show = null; $found_current = false; // 筛选当天未取消的节目,按开始时间排序 $today_shows = array_filter($audition_list, function($row) use ($current_day) { return $row['audition_day'] == $current_day && $row['canceled'] == 0; }); usort($today_shows, function($a, $b) { return strtotime($a['start_time']) - strtotime($b['start_time']); }); // 查找当前正在播出的节目 foreach($today_shows as $show) { $start = strtotime($show['start_time']); $end = strtotime($show['end_time']); $now = strtotime($current_time); if($now >= $start && $now <= $end) { $current_show = $show; $found_current = true; break; } } // 查找下一个节目 if($found_current) { // 找当前节目之后的第一个当天节目 foreach($today_shows as $show) { if(strtotime($show['start_time']) > strtotime($current_show['end_time'])) { $next_show = $show; break; } } // 当天无后续节目则找次日第一个节目 if(!$next_show) { $next_day = $current_day == 7 ? 1 : $current_day + 1; $next_day_shows = array_filter($audition_list, function($row) use ($next_day) { return $row['audition_day'] == $next_day && $row['canceled'] == 0; }); usort($next_day_shows, function($a, $b) { return strtotime($a['start_time']) - strtotime($b['start_time']); }); $next_show = !empty($next_day_shows) ? reset($next_day_shows) : null; } } else { // 当前无节目在播,找当天第一个未开始的节目 foreach($today_shows as $show) { if(strtotime($show['start_time']) > strtotime($current_time)) { $next_show = $show; break; } } // 当天无未开始节目则找次日第一个节目 if(!$next_show) { $next_day = $current_day == 7 ? 1 : $current_day + 1; $next_day_shows = array_filter($audition_list, function($row) use ($next_day) { return $row['audition_day'] == $next_day && $row['canceled'] == 0; }); usort($next_day_shows, function($a, $b) { return strtotime($a['start_time']) - strtotime($b['start_time']); }); $next_show = !empty($next_day_shows) ? reset($next_day_shows) : null; } } // 输出当前节目 echo "<div class='now'>"; if($current_show) { echo "<span>Aktualnie na antenie:</span>"; echo "<span>".$current_show['username']."</span>"; echo "<span>".$current_show['name']."</span>"; echo "<span>Do: ".date("H:i", strtotime($current_show['end_time']))."</span>"; } else { echo "<span>Aktualnie na antenie:</span>"; echo "<span>".$auditionDJ."</span>"; echo "<span>".$auditionTitle."</span>"; } echo "</div>"; // 输出下一个节目 echo "<div class='next'>"; if($next_show) { echo "<span>Następnie:</span>"; echo "<span>".$next_show['username']."</span>"; echo "<span>".$next_show['name']."</span>"; echo "<span>Od: ".date("H:i", strtotime($next_show['start_time']))."</span>"; // 若为次日节目,显示星期提示 if($next_show['audition_day'] != $current_day) { $day_names = ['', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota', 'Niedziela']; echo "<span> (".$day_names[$next_show['audition_day']].")</span>"; } } else { echo "<span>Następnie:</span>"; echo "<span>".$auditionDJ."</span>"; echo "<span>".$auditionTitle."</span>"; } echo "</div>";
代码说明
- 筛选排序:先过滤出当天未取消的节目并按开始时间排序,确保判断顺序正确
- 当前节目判断:遍历当天节目,精准匹配当前时间处于节目时段内的内容
- 下一个节目查找:优先找当天后续节目,无结果则自动匹配次日第一个节目
- 输出逻辑:仅输出当前和下一个节目各一次,避免重复输出无关内容
内容的提问来源于stack exchange,提问作者Ademn
相关产品推荐
相关产品推荐

