※この記事は「2021年4月8日」に更新しました。
PHP でカレンダーを作成します。
前回の続きです。
今回は、リンクを動作させるための仕組みをつくっていきます。
カレンダーを作成する
カレンダーを作成します。
今回の記事のポイントは、以下の通りです。
- リンクを動作させるための準備をする
- 前月、翌月のリンクを作成する
それでは、解説していきます。
リンクを動作させる準備をする
リンクを動作させるための準備をしていきます。
前回のコードの一番先頭部分に、以下のコードを追記していきます。
try { if(!isset($_GET['t']) || !preg_match('/\A\d{4}-\d{2}\z/', $_GET['t'])){ throw new Exception(); } $thisMonth = new DateTime($_GET['t']); } catch (Exception $e) { $thisMonth = new DateTime('first day of this month'); }
ポイントは、以下のコードです。
$thisMonth = new DateTime($_GET['t']);
これに対して、try~catch文を使っています。
例外が発生した場合は、以下のコードを実行します。
$thisMonth = new DateTime('first day of this month');
パラメータである t が正しく取得できないパターンを想定して if文を使っています。
このパターンに当てはまる場合、例外処理へ投げます。
値が入っているか、数字4桁と -(ハイフン)と数字2桁の組合せになっているかを調べています。
前月、翌月のリンクを作成する
前月、翌月のリンクを作成していきます。
前回のコードの HTML 部分を修正していきます。
<thead> <tr> <th><a href="/?t=<?php echo escapeHtml($prev); ?>">«</a></th> <th colspan="5"><?php echo escapeHtml($yearMonth); ?></th> <th><a href="/?t=<?php echo escapeHtml($next); ?>">»</a></th> </tr> </thead>
ここは、カレンダーの表示部分になります(何年何月の箇所)。
escapeHtml という関数を自作して、エスケープ処理をします。
function escaptHtml($s) { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); }
htmlspecialchars関数を使って、HTML にとっての特殊文字を表示できるように変換しています。
続いて、肝心の prev と next の値をつくっていきます。
$dt = clone $thisMonth; $prev = $dt->modify('-1 month')->format('Y-m'); $dt = clone $thisMonth; $next = $dt->modify('+1 month')->format('Y-m'); $yearMonth = $thisMonth->format('F Y');
modify で、タイムスタンプを変更しています。
あとは、2019-11 というような形式、数字4桁(年)- 数字2桁(月)になるようにしています。
サンプルコード【PHP】
今回の記事のサンプルです(PHP)。
スタイルシートに関しては、前回同様なので、第1回目のものをご参照ください。
<?php function escapeHtml($s) { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); } try { if(!isset($_GET['t']) || !preg_match('/\A\d{4}-\d{2}\z/', $_GET['t'])){ throw new Exception(); } $thisMonth = new DateTime($_GET['t']); } catch (Exception $e) { $thisMonth = new DateTime('first day of this month'); } $dt = clone $thisMonth; $prev = $dt->modify('-1 month')->format('Y-m'); $dt = clone $thisMonth; $next = $dt->modify('+1 month')->format('Y-m'); $yearMonth = $thisMonth->format('F Y'); $tail = ''; $PreMonthDay = new DateTime('last day of ' . $yearMonth . ' -1 month'); while ($PreMonthDay->format('w') < 6) { $tail = sprintf('<td class="except">%d</td>', $PreMonthDay->format('d')) . $tail; $PreMonthDay->sub(new DateInterval('P1D')); } $content = ''; $daterange = new DatePeriod( new DateTime('first day of ' . $yearMonth), new DateInterval('P1D'), new DateTime('first day of ' . $yearMonth . ' +1 month') ); foreach ($daterange as $day) { if ($day->format('w') % 7 === 0) { $content .= '</tr><tr>'; } $content .= sprintf('<td class="week_%d">%d</td>', $day->format('w'), $day->format('d')); } $head = ''; $nextMonthDay = new DateTime('first day of ' . $yearMonth . ' +1 month'); while ($nextMonthDay->format('w') > 0) { $head .= sprintf('<td class="except">%d</td>', $nextMonthDay->format('d')); $nextMonthDay->add(new DateInterval('P1D')); } ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>My Calendar</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <table> <thead> <tr> <th><a href="?t=<?php echo escapeHtml($prev); ?>">«</a></th> <th colspan="5"><?php echo escapeHtml($yearMonth); ?></th> <th><a href="?t=<?php echo escapeHtml($next); ?>">»</a></th> </tr> </thead> <tbody> <tr> <td>Sun</td> <td>Mon</td> <td>Tue</td> <td>Wed</td> <td>Thu</td> <td>Fri</td> <td>Sat</td> </tr> <tr> <?php echo $tail . $content . $head; ?> </tr> </tbody> <tfoot> <tr> <th colspan="7"><a href="?t=test">Today</a></th> </tr> </tfoot> </table> </body>
Today のリンク部分はとりあえず、今回の例外処理のテストをしています(次回以降また変更します)。
最後に
いかがでしょうか。
次回は、細かい修正をしていき完成を目指したいと思っています。
日々勉強していきます。