PHP数组日历数据存储问题:实现单日多条目展示及覆盖逻辑优化
Hey there! The main issue you're hitting is using single dates as array keys—this forces each day to only hold one entry, which is why you're losing data when multiple things happen on the same day (like a regular class plus a booking/cancellation). Let's fix this by restructuring your arrays to support multiple entries per date, while keeping your original priority logic (regular classes → bookings/cancellations → school holidays).
Step 1: Restructure Your Arrays
Instead of separate single-value arrays ($datesdata, $timedata, $classiddate), create a single multi-dimensional array where each date maps to a list of entries. We'll also keep a separate array for school holidays since they should override everything:
// Initialize empty arrays $dailyEntries = []; $schoolHolidays = [];
Each entry in $dailyEntries[$date] will be an associative array containing all relevant data for that class/booking/cancellation, like type (to distinguish regular, booked, cancelled, etc.), time, classID, etc.
Step 2: Update Regular Class Data Storage
Modify your regular class loop to push entries into the multi-dimensional array instead of overwriting single values:
// Inside your regular class while loop... for ($i=1;$i<=$n;$i++){ if ($i<10) { $i = "0" . $i; } $currentDate = $yearmonth.$i; $day=date("l",strtotime($currentDate)); if($day==$dayofclass){ $classTime = date("H:i",strtotime($row['time'])); // Push a regular class entry to this date's list $dailyEntries[$currentDate][] = [ 'type' => 'regular', 'classID' => $row['classID'], 'time' => $classTime, 'level' => $row['class_level'], 'title' => $row['class_title'], 'teacher' => $row['teacher'] ]; } }
Step 3: Update Booking/Cancellation Record Storage
Adjust your attendance loop to add entries to the same $dailyEntries array, using the furikae value to set the entry type:
// Inside your attendance while loop... $phpdate = strtotime( $row["class_time"] ); $currentDate = date( 'Y-m-d', $phpdate ); $classTime = date("H:i",strtotime($row['time'])); // Determine entry type based on furikae switch($row["furikae"]) { case 3: $entryType = 'booked'; break; case 2: $entryType = 'cancelled'; break; case 7: case 8: $entryType = 'schedule_change'; break; default: $entryType = 'unknown'; } // Push this entry to the date's list $dailyEntries[$currentDate][] = [ 'type' => $entryType, 'classID' => $row['classID'], 'time' => $classTime // Add any other relevant fields from AttendanceDB/ClassDB here ];
Step 4: Update School Holiday Storage
Store holidays in their own array for easy checking later:
// Inside your school schedule while loop... $phpdate = strtotime( $row["date"] ); $currentDate = date( 'Y-m-d', $phpdate ); $schoolHolidays[$currentDate] = true; // Mark this date as a holiday
Step 5: Display the Calendar with Multiple Entries
When rendering your calendar, for each date:
- First check if it's a school holiday—if yes, show the holiday message
- If not, loop through all entries for that date and display each one individually
Example display logic:
// Assume you're looping through each date in the month... foreach ($datesInMonth as $date) { echo "<div class='calendar-day'>"; echo "<h3>" . $date . "</h3>"; // Check for school holiday first if (isset($schoolHolidays[$date])) { echo "<p class='holiday'>School Closed</p>"; } else { // Show all entries for this date if (isset($dailyEntries[$date])) { // Optional: Sort entries by time usort($dailyEntries[$date], function($a, $b) { return strcmp($a['time'], $b['time']); }); foreach ($dailyEntries[$date] as $entry) { // Format output based on entry type switch($entry['type']) { case 'regular': echo "<p class='regular-class'>" . $entry['time'] . " - " . $entry['title'] . " (Level: " . $entry['level'] . ")</p>"; break; case 'booked': echo "<p class='booked-class'>" . $entry['time'] . " - Booked Class: " . $entry['classID'] . "</p>"; break; case 'cancelled': echo "<p class='cancelled-class'>" . $entry['time'] . " - Cancelled Class: " . $entry['classID'] . "</p>"; break; case 'schedule_change': echo "<p class='schedule-change'>" . $entry['time'] . " - Schedule Adjustment</p>"; break; } } } else { echo "<p>No classes scheduled</p>"; } } echo "</div>"; }
Key Improvements
- No more data overwriting: Each date can hold as many entries as needed
- Clearer entry types: You can easily distinguish between regular classes, bookings, cancellations, and holidays
- Flexible display: Style each entry type differently, or sort entries by time before display
This structure keeps your original priority (holidays override everything else) while allowing multiple entries per day. You can tweak the entry fields and display formatting to match your exact needs!
内容的提问来源于stack exchange,提问作者Benjamin Jones

