PHP日历类同天多事件仅显示首个问题排查求助
PHP日历类同一日期多事件仅显示最早项的问题修复
我开发了一个用于网页展示的PHP日历类,目前日历可正常运行,但存在一个问题:当同一日期添加多个事件时,仅会显示最早创建的那个事件。已调试许久仍未定位原因,希望得到技术指导。
Calendar类代码
<?php class Calendar { private $active_year, $active_month, $active_day; private $events = []; public function __construct($date = null) { $this->active_year = $date != null ? date('Y', strtotime($date)) : date('Y'); $this->active_month = $date != null ? date('m', strtotime($date)) : date('m'); $this->active_day = $date != null ? date('d', strtotime($date)) : date('d'); } public function add_event($txt, $date, $days = 1, $color = '') { $color = $color ? ' ' . $color : $color; $this->events[] = [$txt, $date, $days, $color]; } public function __toString() { $num_days = date('t', strtotime($this->active_day . '-' . $this->active_month . '-' . $this->active_year)); $num_days_last_month = date('j', strtotime('last day of previous month', strtotime($this->active_day . '-' . $this->active_month . '-' . $this->active_year))); $days = [0 => 'Sun', 1 => 'Mon', 2 => 'Tue', 3 => 'Wed', 4 => 'Thu', 5 => 'Fri', 6 => 'Sat']; $first_day_of_week = array_search(date('D', strtotime($this->active_year . '-' . $this->active_month . '-1')), $days); $html = '<div class="calendar">'; $html .= '<div class="header">'; $html .= '<div class="month-year">'; $html .= date('F Y', strtotime($this->active_year . '-' . $this->active_month . '-' . $this->active_day)); $html .= '</div>'; $html .= '</div>'; $html .= '<div class="days">'; foreach ($days as $day) { $html .= ' <div class="day_name"> ' . $day . ' </div> '; } for ($i = $first_day_of_week; $i > 0; $i--) { $html .= ' <div class="day_num ignore"> ' . ($num_days_last_month-$i+1) . ' </div> '; } for ($i = 1; $i <= $num_days; $i++) { $selected = ''; if ($i == $this->active_day) { $selected = ' selected'; } $html .= '<div class="day_num' . $selected . '">'; $html .= '<span>' . $i . '</span>'; foreach ($this->events as $event) { for ($d = 0; $d <= ($event[2]-1); $d++) { if (date('y-m-d', strtotime($this->active_year . '-' . $this->active_month . '-' . $i . ' -' . $d . ' day')) == date('y-m-d', strtotime($event[1]))) { $html .= '<div class="event' . $event[3] . '">'; $html .= $event[0]; $html .= '</div>'; } } } $html .= '</div>'; } for ($i = 1; $i <= (42-$num_days-max($first_day_of_week, 0)); $i++) { $html .= ' <div class="day_num ignore"> ' . $i . ' </div> '; } $html .= '</div>'; $html .= '</div>'; return $html; } } ?>
Calendar.css代码
.calendar { display: flex; flex-flow: column; overflow: scroll; } .calendar .header .month-year { font-size: 20px; font-weight: bold; color: #636e73; padding: 20px 0; } .header{ height: 10%; } .calendar .days { display: flex; flex-flow: wrap; flex-wrap: wrap; } .calendar .days .day_name { width: calc(87.5% / 7); height: 5%; border-right: 1px solid #2c7aca; /* padding: 10px; */ text-transform: uppercase; font-size: large; font-weight: bold; color: #818589; color: #fff; background-color: #448cd6; } .calendar .days .day_name:nth-child(7) { border: none; } .calendar .days .day_num { display: flex; flex-flow: column; width: calc(76.75% / 7); width: calc(87.5% / 7); border-right: 1px solid #e6e9ea; /* border-bottom: 1px solid #e6e9ea; */ /* padding: 10px; */ /* padding: 1%; */ font-weight: bold; color: #7c878d; cursor: pointer; /* min-height: 100px; */ min-height: 20%; /* min-height: 5%; */ height: 5%; background-color: white; } .calendar .days .day_num span { display: inline-flex; width: 30px; width: 10%; font-size: 14px; font-size: small; } .calendar .days .day_num .event { margin-top: 10px; margin-bottom: 200%; font-weight: 500; font-size: 14px; padding: 3px 6px; border-radius: 4px; background-color: #f7c30d; color: #fff; word-wrap: break-word; } .calendar .days .day_num .event.green { background-color: #51ce57; } .calendar .days .day_num .event.blue { background-color: #518fce; } .calendar .days .day_num .event.red { background-color: #ce5151; } .calendar .days .day_num:nth-child(7n+1) { border-left: 1px solid #e6e9ea; } .calendar .days .day_num:hover { background-color: #fdfdfd; background-color: gainsboro; } .calendar .days .day_num.ignore { background-color: #fdfdfd; background-color: black; color: #ced2d4; cursor: inherit; } .calendar .days .day_num.selected { background-color: #f1f2f3; background-color: gainsboro; cursor: inherit; }
问题原因及修复方案
问题并非出在PHP逻辑里,而是CSS样式导致的:.calendar .days .day_num .event中的margin-bottom: 200%;会让第一个事件占据容器内几乎所有可用空间,后续事件被挤出了可视区域,看起来像是只显示了最早的事件。
修复步骤:
- 移除
.event样式中的margin-bottom: 200%;属性 - 可选:根据实际需求调整
margin-top或添加max-height、overflow-y: auto来优化多事件的显示效果
修改后的.event样式示例:
.calendar .days .day_num .event { margin-top: 10px; font-weight: 500; font-size: 14px; padding: 3px 6px; border-radius: 4px; background-color: #f7c30d; color: #fff; word-wrap: break-word; /* 可选:如果事件过多,添加滚动条 */ /* max-height: 60px; */ /* overflow-y: auto; */ }
另外,PHP部分的事件循环逻辑可以优化(比如提前按日期分组事件,避免每天遍历所有事件),但这不是当前显示问题的核心。
内容的提问来源于stack exchange,提问作者Devinc88
相关产品推荐
相关产品推荐

