【PHPソース説明】カレンダー

PHPを学び始めてまだ数か月という時点で、自分の練習用に作ったカレンダーのページを理解を深めるためにブログ記事にしました。

このサイトを作った背景

PHPを学ぶためにオンラインでCODEPREPのサイトで勉強をしており、課題として出てきた「PHPで作るカレンダー」の内容をより深く理解したいと思ったため、そのレッスンを元に、実際にWEBページとして再現しました。並行してCSS、jQueryを勉強していたため、デザイン的なアレンジを少し加え、友人の助言によりライブラリを用いた祝日取得をおこないました。

参考:https://codeprep.jp/books/category/PHP

どんなサイトなのか

概要と工夫した点

このサイトは、サイトを開くと現在の日時を自動的に取得して今月と来月のカレンダーを表示します。工夫した点は以下の通りです。

  1. 元のカレンダーは日曜始まりでしたが、月曜始まりに変更しました。
  2. 土日も平日と同じ色合いだったため、視認性を高めるべく土曜日は背景を水色に、日曜日は背景をピンク色に変更しました。
  3. 元のカレンダーは今日の日付を取得して今月のカレンダーを表示するだけでしたが、来月のカレンダーも同時に表示させました。
  4. ページを開いたときに、それぞれのカレンダーが順番にふわっと表示される効果を付けました。
  5. ライブラリのYasumiを使って日本の祝日を取得し、各カレンダー下に表示しました。

仕組み

①現在の年月から1日~末日までの配列を作成し、7つで折り返す「*」の一覧を作成
②foreach構文を使って、月曜日から日曜日まで順番に日付を配置
※詳しく知りたい方は、ぜひCODEPREPの「PHP実践 カレンダー実装編」を試してください。

CODEPREP PHP実装 カレンダー実装編

使用した関数

require_once — ファイル読み込み(但しスクリプト実行時にファイルが既に読み込まれているかを確認するため、既に読み込まれている場合は読み込まない。)

Date — ローカルの日付・時間の書式化

mktime — 日時の Unix タイムスタンプの取得

具体的なコードの内容

①class Calendar内にて、現在の年月から1日~末日までの配列を作成し、7つで折り返す「*」の一覧を作成します。このとき、月曜日始まりにしたかったため、日曜日を示す0の値が来た時に折り返すよう設定しました。

class Calendar{
    private $year;
    private $month;
    public function __construct($y,$m){
        $this->year = $y;
        $this->month = $m;
    }
    public function create_rows(){
        $last_day = date("j", mktime(0,0,0,$this->month+1,0,$this->year));
      
        //  echo $this->year."年".$this->month."月の最終日は".$last_day."日です";
        $rows = array();
        $row = self::init_row();
        for($i=1;$i <= $last_day; $i++){
            //番号で曜日を取得
            $date = Date("w", mktime(0,0,0,$this->month,$i,$this->year));
            $row[$date] = $i;
            //$date==6(土曜日)指定を0(日曜日)に変更
            if($date == 0|| $i == $last_day){
                $rows[]= $row;
                $row = self::init_row();
            }
        }
        return $rows;
    }
    public function get_info(){
        return " month : " . $this->year . "-" . $this->month;
    }
    private static function init_row(){
        $ary = array();
        for( $i = 0; $i <= 6; $i++ ){
            $ary[] = "*";
        }
        return $ary;
    }
}

②何月のカレンダーなのかをget_info()関数をechoすることで表示させます。

echo 'This' . $cal->get_info();

③HTMLでカレンダーの一行目となる月曜日~日曜日を配置します。このとき、土日はそれぞれ背景を水色とピンク色に変更出来るよう、<colgroup span>で表の縦の列をグループ分けし、週末のみ<th>タグにクラスを設定しました。

    </h1>
    <table>
    <colgroup span="5"></colgroup>
    <colgroup span="1" class="sat"></colgroup>
    <colgroup span="1" class="sun"></colgroup>
    <tr>
    <th>月</th>
    <th>火</th>
    <th>水</th>
    <th>木</th>
    <th>金</th>
    <th class="sat">土</th>
    <th class="sun">日</th>
    </tr>

④foreach構文を使って、月曜日から日曜日まで順番に日付を配置しました。

EOL;
foreach( $cal->create_rows() as $row ){
    echo "<tr>";
    //$i=1(月曜日)から開始で6(土曜日)までループ、最後に0(日曜日)をecho    
    for($i=1;$i<=6;$i++){
        echo "<td>".$row[$i]."</td>";
    }
    echo "<td>".$row[0]."</td>";
    
    echo "</tr>";
}
    echo "</table>";
echo <<< EOL

初見だったこと

ヒアドキュメント

ヒアドキュメント(EOL; およびecho <<< EOL)という書き方が使われており、これらを学んだことがなかったため、PHPの記述部分、HTML記述部分を認識するのに少し苦労しました。なお、「EOL」という表記は他の言葉の略語にもなっている(主にEnd Of Life=製品のサポート終了、提供終了などの意味)ため、大変検索で探しづらい印象を持ちました。

ヒアドキュメントに関する簡潔な記事を見つけたので、参考にリンクを貼っておきます。

参考:http://www.php-labo.net/tutorial/php/heredocument.html

なお、ヒアドキュメントで使用される単語は数種類あるようで、EOMは End Of Message、EODはEnd of Document、EOFはEnd of Fileの略として使われているようです。ならば、EOLはEnd Of Lineかなと推測しています。

ライブラリの使用

今回初めてライブラリを使用しました。APIやライブラリを使いこなせるととても便利とは聞いていましたが、具体的な導入方法がわからなかったので、検索を重ねて手探りで3週間ほどかかってしまいました。

1. Composerの導入

ターミナルにコマンドを打ち込んでインストールします。

参考:https://getcomposer.org/doc/00-intro.md#globally

2. YASUMIの導入

こちらもターミナルにコマンドを打ち込み、さらにPHPファイル冒頭に一行追加することでインストールします。

参考:https://azuyalabs.github.io/yasumi/gettingstarted/

3. Yasumi Cookbook(Yasumi Recipes)を参照

公式ページにある記述を参考に使い方を確認し、記述を進めます。今回は、$SOM(Start Of Month)と$EOM(End Of Month)を今日の日付から取得しておき、その範囲内の祝日をechoする方法をとりました。

EOL;
  /* 今月の祝日 */
    foreach ($holidays->getHolidayDates() as $date) {
        if($date >= $SOM && $date <= $EOM){
        echo $date . '<br/>';
        }
    } 
echo <<< EOL

今後の課題

当初下記2点を盛り込む予定でしたが、現時点ではおこなえていないので、今後対応する予定です。

(未実装)本日の日付および祝日を強調表示する効果を付けます。
(未実装)新月・満月の日がわかるように表示します。