【動画・サンプルコード】PHPカレンダーの作り方

この記事では「PHP でカレンダーを作る方法」を紹介します。
作成するのは以下のようなカレンダーです。(年月の横にある < > をクリックすると、前月・次月のカレンダーも表示できます。)
カレンダー作成の流れ
最初に HTML と CSS でカレンダーのレイアウトを用意して、それをもとに PHP でカレンダーを出力していきます。
CSS は書かなくても良いですが、せっかくなので Bootstrap と Google Fonts を使ってカレンダーらしくしていきましょう。
Bootstrap はフレームワークと言って、難しいコードを書かずに綺麗なテーブルやフォームを用意することができるものです。
CSS が苦手という方やレイアウトの作成に時間を掛けたくない場合に役立ちます。JavaScript でモーダルや切り替えタブなども簡単に作成することができます。
Google Fonts は、たった数行のコードをコピーするだけで800種類以上のフォントを無料で使うことができるサービスです。ブラウザによってフォントがバラバラだったり、文字が読みづらくならないように、フォントを指定しておきましょう。
カレンダー作成には、ループ・ GET ・ date 関数など PHP の基礎がたくさんつまっています。
特に date 関数など日付関連の処理はよく使用するものなので、カレンダーを作りながら慣れておくと良いと思います。
ぜひ、オリジナルのカレンダーを作ってみてください。
動画
動画では Bootstrap / Google Fonts が古い仕様になっています。解説では最新のものを使用しているので、そちらもお読みください。
Part1 : HTML & CSS
Part2 : PHP
解説
1. php ファイルを作成する
ファイル名は何でも良いので、ファイル名.php のように php ファイルを作成してください。
ここでは index.php として進めていきます。
2. HTML
作成した index.php を開いて、以下のように HTML を書いてください。
class について
42行目の today クラスは「今日の日付」に色をつけるために用意します。
その他のクラス名 container, mb-5, table-borderd はBootstrap で指定されているクラス名です。あとで Bootstrap を読み込んだ時にレイアウトが変わります。
この時点では、以下のようなカレンダーになっていると思います。

カレンダーがブラウザーの端にあり、日付の間隔も狭くて分かりにくいですね。
これを CSS でカレンダーらしくしていきましょう。
3. CSS
Bootstrap を読み込む
Bootstrap 5 の公式サイトを開きます。
リンク:https://getbootstrap.com/
Get Started をクリックします。

CSS の下にあるコードをコピーします。

コピーしたコードを6行目に追加します。
Google Fonts を読み込む
検索、または以下のリンクから Google Fonts のサイトを表示します。
https://fonts.google.com/
好きなフォントを選んでクリックします。Language メニューから Japanese を選択することもできます。

今回は Noto Sans JP を使ってみます。

使いたいサイズの横にある + Select this style をクリックします。
複数使うこともできますが、今回は Regular 400 だけ使います。

画面右側に表示されるコードをコピーして使います。

コピーしたコードを、7~13行目のように追加します。
ブラウザを更新してみてください。Bootstrap とフォントが適用されたでしょうか?

CSS を書く
次に「曜日の色・カレンダーのサイズ」を調整します。
今回は1つのファイルにまとめたいので head タグ内に直接書いていきます。
12~32行目を追加します。
27・30行目:nth-of-type(n)
n 番目の要素を指定できます。
th:nth-of-type(1) は日曜日の th、th:nth-of-type(7)は土曜日の th を指定して、それぞれ色を変更しています。
これでレイアウトは完成です。次はカレンダー部分を PHP で出力していきましょう。

4. PHP
1~82・130~134行目を追加して、119行目を変更します。
3行目 タイムゾーン
date_default_timezone_set('Asia/Tokyo');
タイムゾーンを東京(日本)に設定しています。その他のタイムゾーンはこちら
15行目 形式チェック
if ($timestamp === false) {
GET パラメータに
- index.php?ym=2021-16
- index.php?ym=0-1111
- index.php?ym=2021-aaa
のように存在しない月や文字列が入っていた場合にエラーが起きないよう形式チェックを追加します。
false が返ってきた場合は、現在の年月・タイムスタンプを作成します。
67行目
if ($youbi % 7 == 6
ここでは「週終わりかどうか」つまり「$youbi が 土曜日かどうか」を判定しています。
土曜日の場合 $youbi は必ず 6, 13, 20, 27, 34 となるので、7で割った時の余りが 6 になります。
ですので $youbi % 7 == 6 と書いて判定しています。
date 関数
date($format, $timestamp)
タイムスタンプ($timestamp)から好きな形式($format)の日付を作成することができます。
タイムスタンプとは 1531454282 のように時刻を数値にしたもので、省略した場合は現在時刻が使われます。
例① 今日の年月を取得する場合
date('Y-m'); // 出力例:2021-06
例② タイムスタンプから年月日を取得する場合
date('Y年n月j日', $timestamp); // 出力例:2021年6月1日
よく使うフォーマット | ||
---|---|---|
Y | 年 | 2018, 2020 |
m | 月(ゼロつき) | 01~12 |
n | 月(ゼロなし) | 1~12 |
d | 日付(ゼロつき) | 01~31 |
j | 日付(ゼロなし) | 1~31 |
w | 曜日 | 0:日曜日 1:月曜日… |
t | 月の日数(何日まであるか) | 28~31 |
strtotime 関数の注意点
前月・次月の年月を取得するには mktime 関数と strtotime 関数を使うことができます。
どちらを使っても問題ありませんが、stortotime 関数を使う場合に1つ注意点があります。
strtotime 関数を使うと1ヶ月前・2日後などの日付を簡単に取得できます。
date('Y-m', strtotime('-1 month'));
date('Y-m', strtotime('+2 day'));
date('Y-m', strtotime('2021-07-01 -1 month'));
上の例では、現在日時と2021年7月1日を基準日にしているので問題ありませんが、31日を基準日にした場合にズレが出ます。
例① 7月1日の1ヶ月前の日付を取得する場合
echo date('Y-m-d', strtotime('2021-07-01 -1 month'));
// 出力結果:2021-06-01
例② 7月31日の1ヶ月前の日付を取得する場合
echo date('Y-m-d', strtotime('2021-07-31 -1 month'));
// 出力結果:2021-07-01 ← 6月になりません!
このようなズレが生じないように、このカレンダーでは 1日(その月の最初の日)のタイムスタンプをもとに1ヶ月前の年月を取得しています。
14行目:1日(その月の最初の日)のタイムスタンプを作成
$timestamp = strtotime($ym . '-01');
32行目:1ヶ月前の年月を取得
$prev = date('Y-m', strtotime('-1 month', $timestamp));
strtotime を使う時は、基準となるタイプスタンプの日付にご注意ください!
完成
以上で PHP カレンダーは完成です!
上手く動かない場合は下のサンプルコードをご利用ください。
サンプルコード
動画のサンプルコード:https://gist.github.com/codeforfun-jp/41c…
解説のサンプルコード:https://gist.github.com/codeforfun-jp/76c…
カレンダー開発をさらに詳しく学ぶ

PHP・MySQL でつくるカレンダー開発講座では
- さらに詳しいコード解説
- 予定を MySQL データベースに保存・編集・削除・検索する方法
- タブレット・スマートフォンに対応させる方法
- Datetimepicker の使い方
- 内閣府が配布している祝日 CSV ファイルの使い方
を学ぶことができます。
PHP と MySQL で何か開発してみたい方、より実用的なコードを学びたい方はぜひ挑戦してみてください!
カスタマイズ
カレンダーを月曜はじまりにする方法
カレンダーの最初の曜日を月曜日にしたい場合は、以下の5箇所を変更します。
① 40行目あたり
$youbi = date('N', mktime(0, 0, 0, date('m', $timestamp), 1, date('Y', $timestamp)));
② 51行目あたり
$week .= str_repeat(‘<td></td>’, $youbi-1);
③ 67行目あたりから
if ($youbi % 7 == 0 || $day == $day_count) {
if ($day == $day_count && $youbi % 7 != 0) {
$week .= str_repeat(‘<td></td>’, 7 – $youbi % 7);
}
④ CSS
th:nth-of-type(6), td:nth-of-type(6) {
color: blue;
}
th:nth-of-type(7), td:nth-of-type(7) {
color: red;
}
⑤ HTML
<tr>
<th>月</th>
<th>火</th>
<th>水</th>
<th>木</th>
<th>金</th>
<th>土</th>
<th>日</th>
</tr>
以上でカレンダーを月曜日始まりにすることができます。

有り難うございました。わかりやすい画面で楽しくコード入力でき、カレンダー作成できました。でも私の特徴であるlocalサーバーのインストールに問題があり、まだ完成していません後ほど質問していいでしょうか?fu-na
カレンダー作成できたとお聞きしてとても嬉しいです🙂
ローカルサーバーについては当サイトで紹介しているもの(XAMPP, MAMP)についてのご質問でしたらお答えできるかと思います。
コメントさせて頂きます。
php初心者のものです。
6~10行目までのissetの部分を詳しく教えて頂く事は可能でしょうか?
isset 関数を使うと GET パラメータに値がセットされているかを判定することができます。
118行目で「前月」「次月」のカレンダーを表示するリンクを作成していて、このリンクを押した場合は ?ym=2020-02 のように GET パラメータで「年月」の値が渡されます。
6~11行目では
のカレンダーを表示できるようにしています。
とても分かりやすかったです!ありがとうございます!
ちなみに、よくカレンダーのプログラムで、年月を入力するとその年月のカレンダーが表示されるプログラムがあると思うのですが、そう言ったコードはどういう風にできますか?
これも[’ym’]も使うのですか?
年月を入力してカレンダーを表示するにはフォームを使います。
form を用意して ym という名前の値を GET 送信してみてください
閏年の判定はどうやって行っていますか?
また、前月・翌月リンクのコードで、12の次は13ですがそこから1に戻る方法と、逆に、1から-1の場合は0ですけど12になります。そういった部分はどのコードで実装されているかお教えできますか?
タイムスタンプを使って日付を取得しているので、閏年の判定は自分で行う必要はありません。
前月・翌月のリンクも、date 関数を使ってタイムスタンプを元に作成しています。
$prev = date('Y-m', strtotime('-1 month', $timestamp));
m は 01 から 12 の数値しか返さないので、0 や 13 が表示されることはありません。
phpでカレンダーを作成する方法を、
解りやすくサイトに公開して下さって、ありがとうございます。
phpを勉強しているのですが、「内閣府の祝祭日CSV」を使用して
カレンダーに組み込む方法を考えています。
アドバイスありましたら、よろしくお願い致します。
当サイトを見つけて頂きありがとうございます
カレンダーを表示するたびに CSV ファイルから祝祭日を取得すると効率が悪くなってしまうので
MySQL データベースに CSV の全データを保存 → カレンダー作成時にその月の祝祭日をデータベースから取得
という方法が良いかと思います。
とてもわかりやすかったです!カレンダー作成できました。
もしよければ祝日の表示も記事にしていただけないでしょうか?
(内閣府が出しているCSVを利用して)
お忙しいところ申し訳ありませんがぜひご検討よろしくお願いします!
当サイトを見つけて頂きありがとうございます。
分かりやすかったとお聞きしてとても嬉しいです
CSVを使った祝日の表示方法は、4月に公開予定の「PHP・MySQL でつくるカレンダー講座」内で紹介する予定となっております。
機会がありましたら、そちらをご利用頂ければと思います。
実装のヒントと致しましては
MySQL データベースに CSV の全データを保存 → カレンダー作成時にデータベースから該当月の取得
という方法がおススメです。
お返事ありがとうございます!
4月楽しみに待っております。
これからもサイト楽しみにアップ待っております><!
私もプログラミング勉強頑張ります!!!
現在は他のプログラミング言語が中心になっているのですが、今年は PHP と MySQL の講座や記事も増やせればと思っております。
このサイトが少しでも masu さんのプログラミング学習のお役に立てれば幸いです応援しています!!
お世話になっております。
カレンダーの作成が無事できました!
例えば、作成したカレンダーをクリックしたり、タッチしたりして、選択し、mysqlに格納したりするには、どのように実現できますでしょうか?
当サイトをご利用いただきありがとうございます。
カレンダーの作成ができたとのこと良かったです!
このページでも少し紹介しておりますが、MySQL データベースへの予定の保存や編集・削除・検索方法はプログラミング講座として販売しております。
実装したいことが一致するようでしたら、ぜひご利用頂ければと思います。
https://courses.codeforfun.jp/p/calendar-with-php-and-mysql/