PHPで閏年(うるう年)かどうか判定する

(1/1)
PHPで閏年(うるう年)かどうか判定する
PHP が活躍するのは、ブラウザからの入力に対して何か反応を返すような処理である。
このような処理は、
  1. ブラウザからの入力
  2. PHP による処理、出力
の 2 段階になる。一般的に、1番目は HTML の FORM タグで、2番目が PHP で処理する。そこで今回は、ブラウザから西暦年号を入力し、それが閏年かどうか判定して結果を出力するページを PHP で作ってみることにする。
(2020 年 12 月 5 日)PHP8 での動作確認。

download プログラムを実行する

サンプル・プログラム

上のボタンをクリックして、PHP のソースプログラムをダウンロードしてほしい。
解凍できたら、isleap.php というファイル名で Web サーバ Apache の仮想ディレクトリが通っているディレクトリにセーブすること。
なお、画面に表示している行番号は説明の便宜上のものであり、ソースプログラムには含まれていない。

サンプル・プログラムの実行方法

ブラウザから http://localhost/***/isleap.php (*** はセーブした仮想ディレクトリ名)と入力すると、年を入力するテキストボックスがあらわれるので、適当な西暦年を入力して[調べる]ボタンを押す。すると、同じページに閏年かどうか判定結果が表示される。なお、初回起動時は現在の西暦年が代入される。

HTMLとPHPが混在するページ

0001: <!DOCTYPE html>
0002: <html lang="ja">
0003: <head>
0004: <meta charset="UTF-8">
0005: <title>閏年かどうか判定する</title>
0006: </head>
0007: 
0008: <?php
0009: // ここからPHPプログラム ===========================================

isleap.php の特徴は、HTML タグと PHP プログラムが混在していることである。PHP では、<?php ... ?>で囲まれた部分のみ PHP プログラムとして解釈され、それ以外の部分は HTML として処理される。
冒頭は HTML 5 の宣言部分である。PHP プログラムは、そのあとから始まる。

なお、HTML タグと PHP プログラムを分ける方法として、これ以外に、「PHP で CSV ファイルを読み込む」で取り上げる「ヒアドキュメント」を使った方法などがある。

if文

0018: /**
0019:  * 与えられた年が閏年かどうか判定する
0020:  * @param int $y   西暦年
0021:  * @return bool TRUE:閏年である/FALSE:平年である
0022: */
0023: function isleap($y) {
0024:     $ret = FALSE;
0025:     if ($y % 4 == 0)    $ret = TRUE;
0026:     if ($y % 100 == 0)  $ret = FALSE;
0027:     if ($y % 400 == 0)  $ret = TRUE;
0028:     return $ret;
0029: }

与えられた年が閏年かどうか調べるユーザー定義関数が isleap である。
われわれが日常使っているグレゴリオ暦では、閏年のルールが次のように定められている。
  1. 4 年で割り切れる年は閏年である。
  2. ただし、100 で割り切れる年は平年である。
  3. ただし、400 で割り切れる年は閏年である。
PHPで閏年(うるう年)かどうか判定する
これを忠実にプログラムで表現したユーザー関数が isleap である。

まず、変数 $y が平年であれば変数 $retFALSE を、閏年なら TRUE を代入する。(TRUE, FALSE は PHP があらかじめ用意している定数で、論理値が真なら TRUE、偽なら FALSE のようにして使う)

最初、変数 $ret は FALSE である。次に、変数 $y が 4 で割り切れる場合は $retTRUE を代入する。
割り算の余りは剰余演算子 % で得られる。剰余が 0 に等しいなら $ret に TRUE を代入することを表すのが、if 文 である。if 文 の使い方は、C や Java など、他の手続き型言語と同じである。
そして、変数 $y が 100 で割り切れる場合は変数 $retFALSEを代入する。
最後に、変数 $y が 400 で割り切れる場合は変数 $retTRUE を代入する。

$_POST変数

0031: //メインプログラム
0032: if (isset($_POST['year']) == FALSE)     $year = date('Y');   //初回起動時
0033: else                                    $year = $_POST['year']

前のページから、FORM タグの POST METHOD で渡されたデータを受け取るのが $_POST 変数である。$_POST[名前] のようにして使う。名前の部分は、定数でも変数でも良い。ここでは、FORM のテキストボックス名 year で西暦年を渡すことを想定しているので、$_POST["year"] として受け取る。

ところが、最初にこのプログラムを起動した時には POST で渡されるデータはないので、$_POST['year'] は存在しない。このままでは実行時エラーになってしまう。
PHP では、変数の存在を調べる関数  isset  が用意されている。そこで、 $_POST['year'] が存在しなければ、関数  date  を使って、プログラム実行時の西暦年を変数 $year に代入する。
もし POST 渡しされたデータがあれば、$year には $_POST['year'] の内容を代入する。
ここでは if~else 文 が登場する。

HTMLのFORMタグ部分

0039: <form action="isleap.php" method="post">
0040: 西暦年号=
0041: <input type="text" size="10" name="year" value="<?= $year ?>">
0042: <input type="submit" value="調べる">
0043: </form>

再び HTML になっている部分である。
ここで、FORM タグを使って西暦年を入力している。西暦年は、テキストボックス year に代入され、POST METHOD によってユーザー関数 isleap.php に渡される。自分自身に渡していることがミソである。これを変数 $year に代入するのである。
なお、"<?= $year ?>" のように記述することで、HTML 上に変数 $year の値を展開することができる。

printf関数

0047: if (isleap($year) == TRUE)  printf('%s年は閏年です', $year);
0048: else                        printf('%s年は平年です', $year);

再び PHP プログラムになった。見た目は分断されているが、処理的には 32行目から連続しているのである。
変数 $year が閏年かどうか判定して、画面に判定結果を表示する。
関数  printf  は、指定された書式に応じて引き数の内容を画面に表示する。詳細はリンク先の PHP マニュアルをご覧いただきたい。基本的には C/C++の printf 関数と同じで、数字や文字列を整形出力するのに重宝する。

補足

今回は関数 isleap を作ったが、実は PHP には与えられた年月日の妥当性を検証する関数  checkdate  が用意される。これを使えば、ある年の 2 月 29 日が存在するかどうか調べることによって、閏年の判定ができる。

関数  printf  は C/C++のものと同様と書いたが、価格などを表す際に整数をカンマ区切りすることができない。こんな場合には関数  number-format  を使えばよい。

参考サイト

(この項おわり)
header