問題
PHPで今月のカレンダーを作成するには?
解決策
- 今月の値を取得します。
- 最初の行の空白を1日の曜日の値を用いてセルで埋めます。
- 繰り返し処理で、1日ごとに出力していきます。
- 最後の行の空白を月の最後の日付の曜日の値を用いてセルで埋めます。
PHPによるカレンダーの作成
PHPで今月のカレンダーを作成する方法をご紹介します。
今回はPHPのプログラム「getHoliday」を使用します。
このプログラムについて、過去の記事で紹介していますので、ぜひこちらもご覧ください。
PHPで本日が祝日かどうかを判定してくれる「getHoliday」
DEMOはこちら
カレンダー用のテーブルの準備
まず、カレンダー用のテーブルの準備を行っていきます。
<?php
date_default_timezone_set('Asia/Tokyo');
include("getHoliday.php");
// 年月を取得する
$datecounter = new DateTime("now");
$ym_now = $datecounter->format("Ym");
$ym_label = $datecounter->format("Y年m月");
$y = substr($ym_now, 0, 4);
$m = substr($ym_now, 4, 2);
?>
<h3 class="title-level03"><?php echo $ym_label; ?></h3>
<table class="type05 section-sss">
<tr>
<th><span class="not">日</span></th>
<th><span class="not">月</span></th>
<th><span class="not">火</span></th>
<th><span class="not">水</span></th>
<th><span class="not">木</span></th>
<th><span class="not">金</span></th>
<th><span class="not">土</span></th>
</tr>
<tr>
- 「date_default_timezone_set(‘Asia/Tokyo’)」でタイムゾーンを「東京」に設定します。
- 祝日を認識させるため、PHPのプログラム「getHoliday」を「include(“getHoliday.php”)」で読み込みます。
- 現在の日時から、今月の値として、フォーマット「Ym」(例:2020年6月 → 202006)とフォーマット「Y年m月」(例:2020年6月)を取得して変数に格納しておきます。
- フォーマット「Ym」から年の部分の値(例:202006 → 2020)と月の部分の値(例:202006 → 06)をsustrを使って取得して変数に格納しておきます。
- 日~土のセルを作成します。
最初の行のセルの設定
カレンダーの最初の1日は、セルの最初からというわけではありません。
1日の曜日に応じて、そこまでの分を空白のセルで埋める必要があります。
<?php
// 1日の曜日を取得
$wd1 = date("w", mktime(0, 0, 0, $m, 1, $y));
// その数だけ空白を表示
for ($i = 1; $i <= $wd1; $i++) {
echo "<td> </td>";
}
?>
- 「date(“w”, mktime(0, 0, 0, $m, 1, $y))」で1日の曜日の数値を取得します。
- for文を使って、1日の曜日の数値になるまで空白のtdタグを生成します。
ポイント!
- フォーマット「w」は、「日曜日 = 0」として、0~6:日曜日~土曜日の値を取得してくれます。
- 値を順に「プラス1」して比較していくことで、そのまま曜日を順に参照することができます。
- 日曜日が一番最初のセルなため、for文を使い、変数にプラス1ずつして比較する度に空白セルを追加することで、無理なく1日までのセルを埋めることができます。
日付フォーマット「w」の値
日曜日 | 0 |
---|---|
月曜日 | 1 |
火曜日 | 2 |
水曜日 | 3 |
木曜日 | 4 |
金曜日 | 5 |
土曜日 | 6 |
日付の出力処理
2行目以降の日付の出力処理を行っていきます。
<?php
$d = 1;
while (checkdate($m, $d, $y)) {
$date_d = sprintf('%02d', $d);
$cal_text = $d;
if(isHoliday($y,$m,$date_d)){
echo '<td class="close holiday">'.$cal_text.'</td>';
if(date("w", strtotime(date($y.$m.$date_d))) == 6){
// 今日が土曜日の場合は…
// 週を終了
echo "</tr>";
// 次の週がある場合は新たな行を準備
if (checkdate($m, $d + 1, $y)) {
echo "<tr>";
}
}
}elseif(date("w", strtotime(date($y.$m.$date_d))) == 6){
// 今日が土曜日の場合は…
echo '<td class="sat">'.$cal_text.'</td>';
// 週を終了
echo "</tr>";
// 次の週がある場合は新たな行を準備
if (checkdate($m, $d + 1, $y)) {
echo "<tr>";
}
}elseif(date("w", strtotime(date($y.$m.$date_d))) == 0){
echo '<td class="sun">'.$cal_text.'</td>';
}else{
echo '<td>'.$cal_text.'</td>';
}
$d++;
}
?>
- 日の値として使用する$dに1を設定します。
- 「while (checkdate($m, $d, $y))」で日付が妥当な限り、処理を繰り返していきます。
繰り返す度に$dにプラス1して、日付を1日ずつ進めていきます。 - if文で日付が「祝日か」「土曜日か」「日曜日か」を調べて、該当すればそれ用の処理を行います。
- 日付が土曜日の場合、trの閉じタグを追加します。
- 日付が土曜日の場合、次の日が存在するかどうかを「checkdate($m, $d + 1, $y)」で調べて、存在する場合はtrの開始タグを追加します。
ポイント!
日付が土曜日の場合、次の日が存在するかどうかを「checkdate($m, $d + 1, $y)」で調べて、存在する場合はtrの開始タグを追加します。
最後の行の残りセルの設定
カレンダーの最初の行の時と同じく、最後の日付がセルの最後でない場合があるため、
最後の日付の曜日に応じて、その日以降を空白のセルで埋める必要があります。
<?php
// 最後の週の土曜日まで移動
$wdx = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
for ($i = 1; $i < 7 - $wdx; $i++) {
echo '<td><span class="not"> </span></td>';
}
?>
- 「date(“w”, mktime(0, 0, 0, $m + 1, 0, $y))」で今月の最後の日の曜日の数値を取得します。
- for文を使って、土曜日の数値になるまで空白のtdタグを生成します。
ポイント!
- 「mktime(0, 0, 0, $m + 1, 0, $y)」で来月の0日を指定することで、今月の最後の日を取得してくれます。
- for文で$iを「1」から始めます。
- 曜日の種類の数である「7」から最後の日付の曜日の値「w」(0 ~ 6)を引いた値「7 – (0 ~ 6)」に達しない限りfor文で繰り返し処理を行い、空白セルを追加させることで、最後のセルである土曜日まで空白セルで埋めることができます。
例:最後の日付が火曜日の場合
最後の日付の「w」の値は「3」であり、「7 – 3 = 4」となります。
$iを「1」から始めるので、空白セル追加の処理が3回繰り返されて、残り分の木曜日、金曜日、土曜日の3つ分のセルが埋まります。
今月のカレンダーを作成する、一連の記述例
上記を元に、今月のカレンダーを作成する、一連の記述例は以下になります。
<?php
date_default_timezone_set('Asia/Tokyo');
include("pahooCalendar.php");
//pahooCalendarクラス
$pcl = new pahooCalendar();
$pcl->setLanguage('jp');
// 年月を取得する
$datecounter = new DateTime("now");
$ym_now = $datecounter->format("Ym");
$ym_label = $datecounter->format("Y年m月");
$y = substr($ym_now, 0, 4);
$m = substr($ym_now, 4, 2);
?>
<h3 class="title-level03"><?php echo $ym_label; ?></h3>
<table class="type05 section-sss">
<tr>
<th><span class="not">日</span></th>
<th><span class="not">月</span></th>
<th><span class="not">火</span></th>
<th><span class="not">水</span></th>
<th><span class="not">木</span></th>
<th><span class="not">金</span></th>
<th><span class="not">土</span></th>
</tr>
<tr>
<?php
// 1日の曜日を取得
$wd1 = date("w", mktime(0, 0, 0, $m, 1, $y));
// その数だけ空白を表示
for ($i = 1; $i <= $wd1; $i++) {
echo "<td> </td>";
}
// 1日から月末日までの表示
$d = 1;
while (checkdate($m, $d, $y)) {
$date_d = sprintf('%02d', $d);
$cal_text = $d;
if($pcl->isHoliday($y,$m,$date_d)){
echo '<td class="close holiday">'.$cal_text.'</td>';
if(date("w", strtotime(date($y.$m.$date_d))) == 6){
// 今日が土曜日の場合は…
// 週を終了
echo "</tr>";
// 次の週がある場合は新たな行を準備
if (checkdate($m, $d + 1, $y)) {
echo "<tr>";
}
}
}elseif(date("w", strtotime(date($y.$m.$date_d))) == 6){
// 今日が土曜日の場合は…
echo '<td class="sat">'.$cal_text.'</td>';
// 週を終了
echo "</tr>";
// 次の週がある場合は新たな行を準備
if (checkdate($m, $d + 1, $y)) {
echo "<tr>";
}
}elseif(date("w", strtotime(date($y.$m.$date_d))) == 0){
echo '<td class="sun">'.$cal_text.'</td>';
}else{
echo '<td>'.$cal_text.'</td>';
}
$d++;
}
// 最後の週の土曜日まで移動
$wdx = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
for ($i = 1; $i < 7 - $wdx; $i++) {
echo '<td><span class="not"> </span></td>';
}
?>
</tr>
</table>
参照
以下のサイトが、より詳しく解説してくれています。
【PHPでカレンダーを作成しよう | PHPプログラミングの教科書 [php1st.com]】
https://php1st.com/1001
【PHP関数講座:mktime | そふぃのphp入門】
https://php-beginner.com/function/datetime/mktime.html
コメント