PHP Calendars Done The Easy Way
For a project we've been working on, I recently had to implement a calendar in PHP to show upcoming events. The solution was a wee bit tricky (and pretty annoying), so here it is in all it's glory, in case someone else is looking. It's pretty easily skinnable, and very scalable, so it should fit in nicely with your project.
First things first, check out the demos:
- Unstyled Example
- Semi-styled Example
- Real-World Example
As I found out, the most annoying part was simply getting the start day and end day to be produced dynamically depending on the month it was given. Basically, the page must take in a month (or get the current month if no month is given), and find the start day (Monday, Tuesday, etc.) and end day of that month. Then, a grid must be generated with a counter starting at the start day, and ending at the end day, wrapping around after then seventh column. For this, I went with a table. Don't scream! A table is semantically correct here based on the very nature of a calendar. It's composed of rows and columns, cells for days, etc. Veerle goes more into this decision in one of her blogs.
So on with the code! First, we take the month and year from the $_GET array to decide what month we're going to be displaying. If no month or year is present in the array, we assume the current month.
Pretty simple right? Next , we need to figure out what next month and last month should be, so that the previous and next links will work correctly. Basically all we're doing is adding one month for next month, and subtracting for last month. The catch is that if we add one to December, we need to set the month back to January and increment the year. Vise versa, if we subtract one from January, we set the month to December and decrement the year. Still not too tough.
-
$lastmonth=$month-1;
-
$nextmonth=$month+1;
-
$lastyear=$year;
-
$nextyear=$year;
-
if ($lastmonth==0)
-
{
-
$lastmonth=12;
-
$lastyear=$lastyear-1;
-
}
-
if ($nextmonth==13)
-
{
-
$nextmonth=1;
-
$nextyear=$nextyear+1;
-
}
Now, for some housekeeping, we display the header (which contains the current month and year being displayed) along with links for last month and next month. We then call the showMonth function which displays the month. More on that function in a second.
-
echo "<center><h2 class='alt'><a href=\"calendar.php?month=$lastmonth&year=$lastyear\"><img src='007.png' alt='Previous month' /></a>\n";
-
echo "<a href=\"calendar.php?month=$nextmonth&year=$nextyear\"><img src='008.png' alt='Next month' /></a></h2></center><hr />\n";
-
showMonth($month,$year,$events); //displays the calendar formatted using an html table
You can also replace the next and last links with left and right arrows or whatever you like.
Finally, we display the calendar. I've created a showMonth function which takes the month and year in as parameters and then outputs the calendar. For your own sake, just take this code and run with it. It's pretty self explanatory, so I'm not going to explain it completely here. If you have questions, just ask.
-
function showMonth($month, $year)
-
{
-
// calculate the position of the first day in the calendar (sunday = 1st column, etc)
-
$rows = 1;
-
-
echo "<table>\n";
-
echo "\t<tr><th>Su</th><th>M</th><th>Tu</th><th>W</th><th>Th</th><th>F</th><th>Sa</th></tr>";
-
echo "\n\t<tr>";
-
for($i = 1; $i <= $offset; $i++)
-
{
-
echo "<td></td>";
-
}
-
for($day = 1; $day <= $daysInMonth; $day++)
-
{
-
if(($day + $offset - 1) % 7 == 0 && $day != 1)
-
{
-
echo "</tr>\n\t<tr>";
-
$rows++;
-
}
-
}
-
while(($day + $offset) <= $rows * 7)
-
{
-
echo "<td></td>";
-
$day++;
-
}
-
echo "</tr>\n";
-
echo "</table>\n";
-
}
And that's the basic concept. Feel free to style as you like. You can put a border around the current day, add background images to the cells (as Veerle did), etc.
If you want to get really snazzy, why not read all of the upcoming events from a database, create an array out of them, and pass that array into the showMonth() function as another parameter. That way, you can highlight upcoming events. Maybe make the events clickable and when clicked, a description will pop up in HighslideJS or some Lightbox clone. That's impressive.
Speaking of which, that's exactly what I did. It would be tough for me to describe that further because it really depends on the structure of your database, but if it's something you'd like to implement, don't hesitate to ask me about it and we'll work though it. I thought it was a pretty fun one.
Download it!! Enjoy!










