Ashley Sheridan​.co.uk

PHP Calendar

Posted on

The calendar at the right-hand side of the site is something which I am often asked about. I have seen many examples online, but all seemed needlessly complicated or coded in a particularly odd fashion. Having decided early on that something simple, efficiently scripted and easy to tweak was needed, I created the one which you see on the site. Here is the source code:

<?php $ymDate = date("Y") . '-' . date("m"); $firstDay = $ymDate . '-01'; $lastDay = $ymDate . '-' . date("t"); $event = array();   $query = "SELECT `type`,`summary`,`date` FROM `calendar` WHERE `date`>='$firstDay' AND `date`<='$lastDay'"; $result = mysql_query($query); while($row = mysql_fetch_array($result)) { $event[$row['date']] = array(); $event[$row['date']]['type'] = $row['type']; $event[$row['date']]['summary'] = $row['summary']; }   print '<table id="calendar">'; print '<caption title="calendar of events for this month">' . date("F Y") . '</caption>'; print '<thead>'; print '<tr><th><abbr title="Sunday">S</abbr></th><th><abbr title="Monday">M</abbr></th><th><abbr title="Tuesday">T</abbr></th><th><abbr title="Wednesday">W</abbr></th><th><abbr title="Thursday">T</abbr></th><th><abbr title="Friday">F</abbr></th><th><abbr title="Saturday">S</abbr></th></tr>'; print '</thead>';   $count = 1; while($count <= date("t")) { print '<tr>'; for($i=0; $i<7; $i++) { $timestamp = mktime(0, 0, 0, date("m"), $count, date("Y")); if(date("w", $timestamp) == $i && $count <= date("t")) { // check to see if an event is associated with this day if(isset($event[date("Y-m-d", $timestamp)])) { print '<td class="' . $event[date("Y-m-d", $timestamp)]['type'] . '">'; print '<a href="calendar.php?date=' . date("Y-m-d", $timestamp) . '" title="' . $event[date("Y-m-d", $timestamp)]['summary'] . '">'; print $count; print '</a>'; print '</td>'; } else { print '<td>' . $count . '</td>'; } $count ++; } else { print '<td></td>'; } } print '</tr>';   } print '</table>'; ?>

The code can be broken up into several parts, each of which I'll explain below:

  1. Initialisation
  2. Database query and event array creation
  3. Main date loops
  4. Event check and display

Line 2 creates a string in the form of 'year-date' (e.g. for today.) Lines 3 and 4 create strings for the first and last days of the month, using the string from line 2 as a building block. Line 5 creates an empty array for use later in the database query.

Lines 7 & 8 query the calendar table in the database for any dates in the given range, using the date strings created before. If you are connecting to a non MySQL database, the query may be slightly different, and the date strings may change. The loop in lines 9-14 cycle through any results found by the query. For each one found, an array is created inside the $event array (with the date string as the index) marking the type and the summary.

Line 22 sets a counter variable, which will be used inside the while loop to determine when to break out of it. The while loop continues until the count is greater than the number of days in the current month.

Line 26 sets up a loop for each day of the week. Line 28 creates a timestamp using the counter variable (which is the day of the month) as a seed. The day of the week for this timestamp is then checked in line 29 against the day of the week (making a final check against the counter as it can increment beyond the days of the month inside the days of the week loop). If the day of the week is not equal to $i (the day of the week loop variable) an empty table cell is displayed, but if it matches, the event check is processed.

The if statement in line 32 checks the $event array for the current date, and if it finds such an array element, it displays a cell containing the counter variable (day of month) as a link, using the 'type' retrieved from the database query as the class, allowing CSS to change the appearance of the cell. If the date does not exist in the $event array, just the day of the month is displayed in the cell (lines 40-43).