作成するカレンダーのイメージ
※以下の内容は[php1st]の「3-4 スケジュール帳(P.192~)」から、カレンダーの作成に関する内容を抜粋して再構成したものです。
これから、次のようなカレンダーを作成します。簡単すぎず難しすぎず、PHPの基礎が習得できたか力試しになり、スケジュール帳や予約への応用など、今後の学習の展望も見えてきます。ざっとPHPの基礎を習得した方は、ぜひ、チャレンジしてみてください。
ポイントは2つあります。1つは行列形式のレイアウトの作成方法、もう1つは、そのレイアウトに1から31までの日付を表示していく方法です。特に、新たな週を作るための改行が重要です。
ステップ0:行列形式へのレイアウトにはtableタグを使う
PHPスクリプトを記述する前に、準備として行列形式のレイアウトを作成するHTMLのtableタグを紹介しておきます。2行2列の簡単なテーブルを例に、その構造を見てみましょう。
<table border="1"> <tr> <td>1</td> <td>2</td> </tr> <tr> <td>3</td> <td>4</td> </tr> </table>
テーブル全体は<table>~</table>の間に定義し、行を<tr>~</tr>、列(セル)を<td>~</td>の間に記述します。<td>~</td>を1から7まで繰り返せば1日から7日まで表示でき、<tr>~</tr>を5回繰り返せば、1週目から5週目までの行が作成できることはイメージできたでしょうか。早速、1日から31日までの日付を表示していきましょう。
ステップ1:1日から月末日まで表示する(while文を使う)
1日から月末日までの日付を表示するには、while文が役立ちます。[php1st](P.105)で作成したコードを利用して、好きな年月の日付を1日から月末日まで表示するコードを準備しましょう。次の例では、2012年2月の日付を表示しています。
<?php $y = 2012; $m = 2; $d = 1; while (checkdate($m, $d, $y)) { echo $d; $d++; } ?>
○実行結果
1234567891011121314151617181920212223242526272829
checkdate関数の3つのパラメータ($m, $d, $y)はそれぞれ、月、日、年を示しています。while文によって$dが1、2、3…と変化するので、実行すると、上のように1から月末日までの数値($d)が単純に1行で表示されます。
ステップ2:日付を行列形式にレイアウトする(tableタグを使う)
ここから、カレンダーらしくするため、tableタグで作成するレイアウトの中に、$dを表示していきましょう。具体的には、tableタグの列(セル)を繰り返す「<td></td>」を「<td>{$d}</td>」になるように変更します。
<table> <tr> <td>ここに$dを埋め込む</td> </tr> </table>
<table border="1"> <tr> <?php $y = 2012; $m = 2; $d = 1; while (checkdate($m, $d, $y)) { echo "<td>$d</td>"; $d++; } ?> </tr> </table>
ステップ3:土曜日で改行する(if文を使う・</tr>を出力する)
カレンダーらしくするため、土曜日で改行しましょう。ここで言う改行とは、「</tr>」を出力してテーブルの行を終了するということです。さらに、次の週があるなら、「<tr>」を出力して新たな行を準備する必要があります。そのイメージは次のようになります。
日付を表示するwhile文の中に、行(週)を終了して新たな週を開始するコードを記述しましょう。まず、土曜日で週を終了するには次のコードを記述します。
// 今日が土曜日の場合は… if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) { // 週を終了 echo "</tr>"; }
※まだ続きがあるので、このコードは入力する必要はありません。
今日の曜日番号が6の場合は「</tr>」を出力しています。「date(“w”)」によって、0(日曜日)から始まる曜日番号を取得できます。その番号が6、つまり、土曜日の場合は「</tr>」と出力して行を終了するということです。
ステップ4:新たな週を準備する(<tr>を出力する)
続いて、新たな週を準備します。その条件は「次の日が存在する場合は」です。日付が妥当か調べるcheckdate関数を使っています。改行した土曜日の次の日が有効な日付であれば、次の週が存在するということです。
// 今日が土曜日の場合は… if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) { // 週を終了 echo "</tr>"; // 次の週がある場合は新たな行を準備 if (checkdate($m, $d + 1, $y)) { echo "<tr>"; } }
このコードを、while文で日付を表示した直後に記述します($d++の前)。
ステップ5:1日の曜日まで空白を出力する(for文を使う)
なんとなくカレンダーらしくなってきましたが、最初の週に違和感があります。毎月1日は必ずしも左端(日曜日)とは限らないので、1日の該当する曜日まで空白を出力して移動する必要があります。それには、毎月1日の曜日番号を調べて、その位置まで空白を出力していきます。そのイメージは次のようになります。
空白を出力するというのは、「<td> </td>」のように何も表示しない列を出力するということです(レイアウトの都合で全角スペースを出力しています)。これを曜日番号の数だけ繰り返すことで、1日の日付を妥当な曜日まで“移動”することができます。この処理をコードにまとめると次のようになります。while文で1日から月末日までの表示を始める直前に記述します。
// 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)) { …略… }
ステップ6:月末日から土曜日まで空白を出力する(for文を使う)
かなりカレンダーらしくなりましたが、月末日の曜日は必ずしも土曜日ではないことに注意が必要です。上の調整と同じように、最後の週に表示される月末日が土曜日以外の場合は土曜日まで空白を出力していく必要があります。そのコードをまとめます。これは、1日から月末日までの表示が終わった直後に記述します。
// 1日から月末日までの表示 $d = 1; while (checkdate($m, $d, $y)) { …略… } // 最後の週の土曜日まで移動 $wdx = date("w", mktime(0, 0, 0, $m + 1, 0, $y)); for ($i = 1; $i < 7 - $wdx; $i++) { echo "<td> </td>"; }
ステップ7:カレンダーの年月を現在の年月にする(date関数・substr関数を使う)
これで、指定した年月のカレンダーを表示できるようになりました。ただし、年月を示す$y、$mには固定値が入っています。ここから先の作業で、選択メニューで選んだ年月を表示するカレンダーにカスタマイズしやすいように、現在の年月を表示するように変更しておきましょう。
それには、スクリプトの先頭で現在の年月を6桁で取得して、4桁の年($y)と2桁の月($m)に分解します。substr関数がピンとこないときは、[php1st]の文字列関数のページ(P.61)も参考にしてください。
<?php // 年月を取得する $ym_now = date("Ym"); $y = substr($ym_now, 0, 4); $m = substr($ym_now, 4, 2); ?> <table border="1"> …tableタグ以下省略…
ステップ8:曜日ラベルを表示する(thタグを使う)【完成】
最後に、曜日ラベルを追加しておきましょう。それには、thタグを使います。tableタグの直後に記述します。以下に示す実際の記述を見れば、使い方はなんとなくわかるのではないでしょうか。
<table border="1"> <tr> <th>日</th> <th>月</th> <th>火</th> <th>水</th> <th>木</th> <th>金</th> <th>土</th> </tr> …略…
このように、<tr>~</tr>の中に曜日ラベルを追加すると、現在の年月のカレンダーが完成です。実行結果は2012年5月の例です。
カレンダーのテンプレート
カレンダーからPHPスクリプトを取り除いたテンプレートを用意しました。それぞれのステップについて、理解できたか確認しながらPHPスクリプトを記述してみましょう。できるだけコピーペーストせずに、実際に入力してみることが重要です。
<?php // ステップ7:現在の年月を取得する(date関数・substr関数) ?> <table border="1"> <tr> <th>日</th> <th>月</th> <th>火</th> <th>水</th> <th>木</th> <th>金</th> <th>土</th> </tr> <tr> <?php // ステップ5:1日の曜日まで空白を表示(for文) // ステップ1:1日から月末日までを表示(while文) // ステップ2:今日の日付を表示(<td>~</td>) // ステップ3:今日が土曜日の場合は…(if文) // ステップ3:週を終了(</tr>) // ステップ4:次の週がある場合は新たな行を準備(if文・<tr>) // ステップ6:最後の週の土曜日まで移動(for文) ?> </tr> </table>
カレンダーのカスタマイズと応用
シンプルなカレンダーは完成です。ここからは、必要に応じてフォームの知識を付けて、どんどんカスタマイズしていきましょう。[php1st]では、最終的にスケジュール帳へと加工していきます。1行ずつ入力していくわけではないので、要点をしっかり習得しましょう。
ポイントは、カレンダーでクリックしてスケジュール登録画面に移動する方法です。メールフォームのように「送信」ボタンをクリックして画面を切り替えるPHPスクリプトとは異なる考え方が必要です。
スケジュール帳のサンプルPHPスクリプト自体は、当Webサイトのトップページからダウンロードすることができますが、PHP入門にチャレンジしたばかりの方は、[php1st]の本文で学習していただくことをおすすめします。