目次
サンプル・プログラム
解凍できたら、isleap.php というファイル名でWebサーバ Apache の仮想ディレクトリが通っているディレクトリにセーブすること。
なお、画面に表示している行番号は説明の便宜上のものであり、ソースプログラムには含まれていない。
バージョン | 更新日 | 内容 |
---|---|---|
1.4.0 | 2024/02/12 | 早期リターン版 isLeapYear2() 追加 |
1.3.0 | 2020/12/05 | 関数名、変数名を読みやすくした |
1.2.1 | 2020/12/05 | PHP8動作確認 |
1.2.0 | 2017/03/18 | bug-fix |
1.1.0 | 2014/07/06 | HTML5対応 |
サンプル・プログラムの実行方法
HTMLとPHPが混在するページ
1: <!DOCTYPE html>
2: <html lang="ja">
3: <head>
4: <meta charset="UTF-8">
5: <title>閏年かどうか判定する</title>
6: </head>
7:
8: <?php
9: // ここからPHPプログラム ===========================================
冒頭はHTML 5の宣言部分である。PHPプログラムは、そのあとから始まる。
なお、HTMLタグとPHPプログラムを分ける方法として、これ以外に、「PHPでCSVファイルを読み込む」で取り上げる「ヒアドキュメント」を使った方法などがある。
if文
18: /**
19: * 指定した年がうるう年かどうか判定する.
20: * グレゴリを暦の定義に忠実に記述した.
21: * @param int $year 西暦年
22: * @return bool TRUE:うるう年/FALSE:平年
23: */
24: function isLeapYear($year) {
25: $result = FALSE;
26: if ($year % 4 == 0) $result = TRUE;
27: if ($year % 100 == 0) $result = FALSE;
28: if ($year % 400 == 0) $result = TRUE;
29: return $result;
30: }
われわれが日常使っているグレゴリオ暦では、うるう年のルールが次のように定められている。
- 4年で割り切れる年はうるう年である。
- ただし、100で割り切れる年は平年である。
- ただし、400で割り切れる年はうるう年である。
まず、変数 $year が平年であれば変数 $result に FALSE を、うるう年なら TRUE を代入する。(TRUE, FALSE は PHP があらかじめ用意している定数で、論理値が真なら TRUE、偽なら FALSE のようにして使う)
最初、変数 $result は FALSE である。次に、変数 $year が4で割り切れる場合は $result に TRUE を代入する。
割り算の余りは剰余演算子 % で得られる。剰余が0に等しいなら $result に TRUE を代入することを表すのが、if文 である。if文 の使い方は、CやJavaなど、他の手続き型言語と同じである。
次に、変数 $year が400で割り切れる場合は変数 $result に TRUE を代入する。
最後に、変数 $result を戻り値として返す。
早期リターン
32: /**
33: * 指定した年がうるう年かどうか判定する.
34: * 早期リターン版.
35: * @param int $year 西暦年
36: * @return bool TRUE:うるう年/FALSE:平年
37: */
38: function isLeapYear2($year) {
39: if ($year % 400 == 0) return TRUE;
40: if ($year % 100 == 0) return FALSE;
41: if ($year % 4 == 0) return TRUE;
42: return FALSE;
43: }
これをフロー図にしたものが左図で、プログラムに実装したものがユーザー関数 isLeapYear2 である。
このように、途中で関数から return することを早期リターンと呼ぶ。
以前は構造化プログラミング手法では好ましくないとされていた書き方だが、最近では受け入れられている。
$_GET変数
45: //メインプログラム
46: if (isset($_GET['year']) == FALSE) {
47: $year = date('Y'); //初回起動時は現在年を代入
48: } else {
49: $year = $_GET['year'];
50: }
ところが、最初にこのプログラムを起動した時には GET で渡されるデータはないので、$_GET['year'] は存在しない。このままでは実行時エラーになってしまう。
PHPでは、変数の存在を調べる関数 isset が用意されている。そこで、 $_GET['year'] が存在しなければ、関数 date を使って、プログラム実行時の西暦年を変数 $year に代入する。
もしGET渡しされたデータがあれば、$yearには $_GET['year'] の内容を代入する。
ここでは if~else文 が登場する。
グループ化
if (isLeapYear($year) == TRUE) { printf('%s年はうるう年です.', $year); }
else { printf('%s年は平年です.', $year); }
PHPでは、セミコロン ; で1つの文(式)の終わりを意味する。if~else文の中に複数の文(式)を記述したいときは、このようにグループ化する(この例では1文しか入っていない)。
PHPは Python と異なり、グループの中にインデントを置くかどうかは自由である(Python は、ブレース {...}の代わりにインデントによってブロックを識別しているため、インデントは必須)。
したがって、下記のような書き方をしてもいい。
if (isLeapYear($year) == TRUE) { printf('%s年はうるう年です.', $year); }
else { printf('%s年は平年です.', $year); }
if (isLeapYear($year) == TRUE) printf('%s年はうるう年です.', $year);
else printf('%s年は平年です.', $year);
if (isLeapYear($year) == TRUE): printf('%s年はうるう年です.', $year);
else: printf('%s年は平年です.', $year); endif;
HTMLのFORMタグ部分
56: <form action="isleap.php" method="get">
57: 西暦年号=
58: <input type="text" name="year" id="year" size="10" value="<?= $year ?>">
59: <input type="submit" name="exec" id="exec" value="調べる">
60: </form>
ここで、FORM タグを使って西暦年を入力している。西暦年は、テキストボックス year に代入され、POST METHOD によってユーザー関数 isleap.php に渡される。自分自身に渡していることがミソである。これを変数 $year に代入するのである。
なお、"<?= $year ?>" のように記述することで、HTML上に変数 $year の値を展開することができる。
printf関数
64: if (isLeapYear($year) == TRUE) {
65: printf('%s年はうるう年です.', $year);
66: } else {
67: printf('%s年は平年です.', $year);
68: }
変数 $year がうるう年かどうか判定して、画面に判定結果を表示する。
関数 printf は、指定された書式に応じて引き数の内容を画面に表示する。詳細はリンク先のPHPマニュアルをご覧いただきたい。基本的にはC/C++の printf 関数と同じで、数字や文字列を整形出力するのに重宝する。
補足
関数 printf はC/C++のものと同様と書いたが、価格などを表す際に整数をカンマ区切りすることができない。こんな場合には関数 number-format を使えばよい。
質疑応答
フローチャートの時点で間違ってます。【回答】
閏年の定義は
年が4で割り切れたら閏年、
年が4で割り切れるが100で割り切れたら平年、
年が4で割り切れ、100で割り切れるが、400で割り切れたら閏年です。
西暦2000年(平成12年)は閏年、西暦2100年(令和82年)は平年です。
フロー図が誤っていました。訂正します。
その他、Twitterでご指摘いただいた皆様、ありがとうございます。
参考サイト
- オリンピック・イヤーは閏年(うるう年)か?:ぱふぅ家のホームページ
- 西暦2400年はうるう年? うるう年じゃない?:@IT
このような処理は、