We have a new website (We've moved)! So go check out Phosphorus.co

Make a Calendar in PHP

Posted in PHP, Tutorials
calendar

Hello, and welcome to another PHP tutorial. This one will teach you how to make a nice PHP calendar (in PHP of course!). When I started out in PHP I always wanted to know how to make a calendar, but could never find the tutorial to do it. So i figured I’d write my own up, to help anyone who is in a similar situation to what I was in. Click the read link to find out more.





Step 1. Getting Started and defining variables

If you’re a bit rusty, or are new to PHP you might want to check out our Short beginners guide, to get the basics down before you start this tutorial. Start the PHP document as you’d start any other, with a PHP open and close tag:

1
2
3
<?php
 
?>

After that I decided to get the main variables sorted out. This is also pretty easy, it just requires some knowledge of the date and time functions. First of all, I decided that my PHP Calendar would be dynamic, as in, I could go through the months, and even the years.

So first, what I did was to get the ?month= part of the url.

1
2
3
4
5
6
7
8
9
 
 
if($_GET['month']) {
	$month = $_GET['month'];
}
else {
	$month = date('n');
	$_GET['month'] = date('n');
}

Okay I’m sure this must look difficult, but let me explain it line by line.

1
if($_GET['month']) {

What we’re saying there, is if we can get the month from the url, then we will do whatever is inside the curly brackets. $_GET is a global variable, and month is what we’re trying to get from the url.

1
2
	$month = $_GET['month'];
}

Then what we do is we put the month (which we get from the url again) into a variable called month, and close the if statement with a curly bracket.

1
2
3
4
5
 
else {
	$month = date('n');
	$_GET['month'] = date('n');
}

Otherwise (else), we set the month variable to the current month, as a default value if no other value is given. We also set $_GET['month'] to the current month (that’s what the date(‘n’) bit does, it gets a numerical value for the month). You can’t see it in the url this time, but it is there. If you’re new to the whole date() function shindig, you might wanna check out this page: PHP Date Function. Next I did the same for the year:

1
2
3
4
5
6
7
8
 
if($_GET['year']) {
	$year = $_GET['year'];
}
else {
	$year = date('Y'); // Year
	$_GET['year'] = date('Y');
}

Okay, if you understood the last bit, you should probably understand this bit. We’re doing exactly the same thing here only with the year. We’re saying, if we can get the year from the url, then put it in a variable. Otherwise, the year is the default year (current year, thats what date(‘Y’) does, again.), and so is $_GET['year'] since it is not defined. Now that we have all this url business sorted out, let me give you an example of a url. Say that you are viewing July 2006. The url would look something like this: ?month=7&year=2006. See how that works? July is the 7th month, and the year is 2006. Lets move on. Next I defined 4 more variables, that control the date, etc.

1
2
3
4
$firstday = mktime(0, 0, 0, $month, 1, $year);
$number = cal_days_in_month(CAL_GREGORIAN, $month, $year); // Number of Days in a Month
$title = date('F', $firstday); // Month name
$day = date('D', $firstday); // Day

This might look a bit daunting at first, but lets break it down.

1
$firstday = mktime(0, 0, 0, $month, 1, $year);

All that the above variable does is gets the first day of the current month (and year), as something called a unix timestamp.

1
$number = cal_days_in_month(CAL_GREGORIAN, $month, $year); // Number of Days in a Month

Another basic function, which gets the number of days in the month, using the gregorian calendar.

1
2
$title = date('F', $firstday); // Month name
$day = date('D', $firstday); // Day

These lines find the month name using the timestamp we defined earlier as $firstday, and the name of the first day, again, using the timestamp we got earlier. Now that we’ve got the basic data defined, lets move on to some more intricate stuff.

Step 2. Finding out what the first day is called

So next we’re going to find out what the first day is, and then set a break before that. This is so that we don’t end up with the 1st beng a thursday, and then displaying in a column which should be for sundays.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
if($day == "Sun") {
	$before = "0";
}
elseif($day == "Mon") {
	$before = "1";
}
 
elseif($day == "Tue") {
	$before = "2";
}
 
elseif($day == "Wed") {
	$before = "3";
}
 
elseif($day == "Thu") {
	$before = "4";
}
 
elseif($day == "Fri") {
	$before = "5";
}
 
elseif($day == "Sat") {
	$before = "6";
}

This is actually pretty straight forward. We’re just setting a variable called before, depending on what day the first day of the month is. If the first day of the month is Sunday, then there is no need to move the calandar at all, therefore, “before” is zero, because sunday is the first day of the week. However, if it’s Wednesday, and we dont set a break, then it will appear in the first column, which is supposed to be for Sunday. Therefore we need 3 breaks (in the 4th column), where wednesday should be. So we set “before” as 3, for 3 breaks.

Setting the scene

Okay, so I mentioned earlier that I want this to be a dynamic calendar. So we’re going to need links, to move between the different months. This is a pretty straight forward part of code. I’ll show you the links first, and then we’ll define the variables.

1
2
3
echo"<a href='?month=$previousmonth&year=$previousyear'>&laquo;</a>";
echo"&nbsp; $title $year &nbsp;";
echo"<a href='?month=$nextmonth&year=$nextyear'>&raquo;</a>";

I don’t think this needs much explaining. All we’re doing here is echoing out variables that we made previously, well, apart from $previousmonth, $nextmonth, $previousyear and $nextyear. However, lets define those now. Put all of this above the links and title we just made.

1
2
3
4
5
6
7
 
if($_GET['month'] == 12) {
	$nextmonth = 1;
	$previousmonth = $_GET['month'] - 1;
	$nextyear = $_GET['year'] + 1;
	$previousyear = $_GET['year'];
}

To start, what I did was to figure out whether or not this was the 12th month (december). After that I started defining variables. It makes sense logically, that if this month is the 12th month, then the next month will be January, or the first month, and that’s why $nextmonth is 1. However, the $previousmonth will be the current month (which we get from the url), minus 1. If we decided to go to the next year by pressing the next button, it will be the current year (which we get from the url), plus 1. Whereas, the previous year will just be the same, because going back will bring you to november, which is still in the same year. Another important thing to think about is if the month is January:

1
2
3
4
5
6
elseif($_GET['month'] == 1) {
	$previousmonth = 12;
	$nextmonth = $_GET['month'] + 1;
	$previousyear = $_GET['year'] - 1;
	$nextyear = $_GET['year'];
}

So what we’re saying here, is if the month is 1 (elseif), then the previous month is going to be 12, logically. Whereas the next month is going to be the current month, plus 1. The previous year will be the current year, minus one, and next year will be the current year, since the next month is February, which is in the same year as January (1st month). Finally, we’ll finish with the else statement

1
2
3
4
5
6
else {
	$nextmonth = $_GET['month'] + 1;
	$previousmonth = $_GET['month'] - 1;
	$nextyear = $_GET['year'];
	$previousyear = $_GET['year'];
}

So if the month is neither january or december, then the next month will just be the current month + 1, the previous month will be the current month – 1, and the next and previous year will stay the same. Remember to put all of this above the links we made before, or else it won’t work.

Looping it all out

To start this I defined two variables that I will use in the loops:

1
2
$i = 1;
$real = 1 + $before;

we’ll explain these later, when we’re doing the loops. After that I made a table. As much as it pains me to make a table, I felt it was easier than doing a bunch of divs. You’re welcome to change the table to divs if you want.

1
2
 
echo"<table cellpadding='10'><tr>";

Right, so lets make a loop.

1
2
3
4
5
 
while($before > 0) {
	echo"<td> </td>";
	--$before;
}

Okay, so this is where we make the breaks, that I was explaining earlier. We want to leave blank spaces so that Wednesday doesn’t appear in a column which is for Sunday. Let me explain it, line by line

1
while($before > 0) {

All we’re doing here is checking if the $before variable (remember, we defined it earlier) is more than zero, then the loop will continue.

1
2
3
4
 
	echo"<td> </td>";
	--$before;
}

If it is more than zero, then take 1 away from the before variable, and show an empty table element. This will show the correct number of blank spaces, so that we don’t end up with the problem i explained earlier.

1
2
3
4
5
6
7
8
9
10
11
while($i <= $number) {
 
	echo"<td> $i </td>";
 
	$divide = $real / 7;
	if(is_int($divide)) {
		echo"</tr><tr>";
	}
	++$real;
	++$i;
}

We’re nearly done now. Let me explain this loop.

1
while($i <= $number) {

So we’re saying, while $i (which is equal to 1) is less than or equal to (<=) the number of days in the month selected ($number), then the loop will continue.

1
	echo"<td> $i </td>";

So first of all we echo out the number, or date in a table element. However, if we left it like that, it would just be a straight line of numbers. We don’t really want that. To seperate the days by the week they’re in, we use a nifty little trick:

1
	$divide = $real / 7;

You’ll remember that $real variable we defined earlier. Well we try and divide it by 7 here. Then..

1
2
3
	if(is_int($divide)) {
		echo"</tr><tr>";
	}

We check if it is an integer, using the is_int() function. An integer (you may or may not know) is a whole number. So if the $real variable is divisible by 7, then we make a break in the table, using the elements.

1
2
3
	++$real;
	++$i;
}

Finally we add 1 to $real and $i using the ++ operator, so we don’t end up with an never ending loop. Then I closed the loop. To finish off, finish the table we started earlier:

1
2
echo"</tr></table>";
?>

And we’re done. I hope this tutorial proved useful.

Final Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<?php
 
 
if($_GET['month']) {
	$month = $_GET['month'];
}
else {
	$month = date('n');
	$_GET['month'] = date('n');
}
if($_GET['year']) {
	$year = $_GET['year'];
}
else {
	$year = date('Y'); // Year
	$_GET['year'] = date('Y');
}
 
$firstday = mktime(0, 0, 0, $month, 1, $year);
$number = cal_days_in_month(CAL_GREGORIAN, $month, $year); // Number of Days in a Month
$title = date('F', $firstday); // Month name
$day = date('D', $firstday);
 
if($day == "Sun") {
	$before = "0";
}
elseif($day == "Mon") {
	$before = "1";
}
 
elseif($day == "Tue") {
	$before = "2";
}
 
elseif($day == "Wed") {
	$before = "3";
}
 
elseif($day == "Thu") {
	$before = "4";
}
 
elseif($day == "Fri") {
	$before = "5";
}
 
elseif($day == "Sat") {
	$before = "6";
}
 
if($_GET['month'] == 12) {
	$nextmonth = 1;
	$previousmonth = $_GET['month'] - 1;
	$nextyear = $_GET['year'] + 1;
	$previousyear = $_GET['year'];
}
 
elseif($_GET['month'] == 1) {
	$previousmonth = 12;
	$nextmonth = $_GET['month'] + 1;
	$previousyear = $_GET['year'] - 1;
	$nextyear = $_GET['year'];
}
 
else {
	$nextmonth = $_GET['month'] + 1;
	$previousmonth = $_GET['month'] - 1;
	$nextyear = $_GET['year'];
	$previousyear = $_GET['year'];
}
 
 
echo"<a href='?month=$previousmonth&year=$previousyear'>&laquo;</a>";
echo"&nbsp; $title $year &nbsp;";
echo"<a href='?month=$nextmonth&year=$nextyear'>&raquo;</a>";
 
$i = 1;
$real = 1 + $before;
 
echo"<table cellpadding='10'><tr>";
while($before > 0) {
	echo"<td> </td>";
	--$before;
}
 
 
while($i <= $number) {
 
	echo"<td> $i </td>";
 
	$divide = $real / 7;
	if(is_int($divide)) {
		echo"</tr><tr>";
	}
	++$real;
	++$i;
}
 
echo"</tr></table>";
 
 
?>

Share This

 

 
 

Author: Johnny




Johnny is the owner of Webtint and usually the sole contributer to the site (apart from the ocassional guest post).


Comments



Jervy August 15, 2009 at 2:16 pm

thanks man, it helped me very much… good work and more power


Elvinas August 29, 2009 at 6:39 pm

Thanks, really simple and useful calendar. But in this calendar someone can use XSS attack. Need use (int) to protect.


    Jonathan August 29, 2009 at 8:37 pm

    Oh I guess I missed that! Thanks.





Leave us a Comment



Put your name here:

Your email goes here:

Got a Website? Put it here (optional):

And finally, your comment:




Sponsors