PHPではPEARなどのライブラリを利用すると簡単にカレンダーを作成できますが、CakePHPなどフレームワークをベースに開発している場合、あまり他のライブラリを利用したくないこともあります。
また祝日情報を含むイベント情報を簡単に組み込めるカレンダーとして、シンプルなカレンダーを作成してみました。
サンプルはこちら

機能としては指定月のカレンダーを生成し、イベント情報を配列として渡すことで、該当日にイベント内容を表示することができます。
祝日情報の取得の関数「getHolidays()」については、「Googleカレンダーから祝日情報を取得。」をご覧ください。

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
//カレンダーと祝日情報の生成用に年月日の変数を作成
$year = date('Y');
$month = date('n');
$day = 1;
 
//祝日情報の配列(「label」はクラス名として利用します)
$holidays = getHolidays($year);
$holidays['label'] = 'holiday';
 
//テストイベント情報の配列
$tests = array('label' => 'test', date('Ymd') => '本日です(イベントのテスト)');
 
//祝日情報とテストイベント情報を連想配列にまとめます
$events = array($holidays, $tests);
 
//カレンダーの出力
echo getCalendar($year, $month, $day, $events);
 
 
 
//指定月のカレンダーを生成
function getCalendar($year, $month, $day, $events) {
 
	//ヘッダー部分の曜日表示
	$days = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
 
	//本日を取得(20120512)
	$today = date('Ymd');
 
	//1行ごとの順番(1〜7)と、月全体の順番(1〜31(最大))
	$num_row = 1;
	$num_day = 1;
 
	//月の始まる曜日から、前月の空白分を取得
	$num_blank = date('w', mktime(0, 0, 0, $month, 1, $year));
 
	//月の合計日
	$total = $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
 
	//カレンダーのヘッダー部分
	$calendar = '<table class="calendar">';
	$calendar .= '<thead><tr>';
	while ($num_row <= count($days)) {
		$calendar .= '<th>'.$days[$num_row-1].'</th>';
		$num_row++;
	}
	$calendar .= '</tr></thead>';
 
	//カレンダーの本体部分
	$calendar .= '<tbody><tr>';
	$num_row = 1;
 
	//前月の空白分のセルを生成
	while ($num_blank > 0) {
		$label = '';
		$label = ($num_row == 1) ? $label.' sun' : $label;
		$calendar .= '<td class="'.$label.'"></td>';
		$num_blank--;
		$num_row++;
	}
 
	//1日〜31日(最大)までのセルを生成
	while ($num_day <= $total) {
 
		//「$label」は要素のクラス名として、「$content」は祝日などのイベント内容
		$label = '';
		$content = '';
 
		//イベントの配列を走査するためのキーとして、「20120512」の形式で文字列を生成
		$key = $year.sprintf('%02d', $month).sprintf('%02d', $num_day);
 
		//左端なら日曜日、右端なら土曜日のためのラベル(クラス)を付加
		$label = ($num_row == 1) ? $label.' sun' : $label;
		$label = ($num_row == 7) ? $label.' sat' : $label;
 
		//本日の場合もクラスを付加
		$label = ($key == $today) ? $label.' today' : $label;
 
		//イベントの配列があれば、配列を走査
		if (isset($events)) {
 
			//連想配列になっているイベントの配列($event)の中の、各イベント配列ごとに処理
			for ($i = 0; $i < count($events); $i++) {
				$label_event = (isset($events[$i]['label'])) ? $events[$i]['label'] : '';
 
				//イベントの配列に一致するキー(20120512など)があれば、要素を付加
				if (array_key_exists($key, $events[$i])) {
					$label .= ' '.$label_event;
					$content .= '<div class="'.$label_event.'">'.$events[$i][$key].'</div>';
				}
			}
		}
		$calendar .= '<td class="'.$label.'">';
		$calendar .= '<div class="day">'.$num_day.'</div>';
		$calendar .= $content;
		$calendar .= '</td>';
		$num_day++;
		$num_row++;
 
		//1行の終わり(7日目)ごとに、新しい行を開始
		if ($num_row > 7) {
			$calendar .= '</tr><tr>';
			$num_row = 1;
		}
	}
 
	//月の最終日以降の空白分のセルを生成
	while ($num_row > 1 && $num_row <= 7) {
		$label = '';
		$label = ($num_row == 7) ? $label.' sat' : $label;
		$calendar .= '<td class="'.$label.'"></td>';
		$num_row++;
	}
 
	//カレンダーの終了
	$calendar .= '</tr></tbody></table>';
 
	//文字列として生成したカレンダーを返す
	return $calendar;
}
?>

CakePHPで利用する場合には、コンポーネントとして登録しておくと使い勝手が良いかもしれません。