PHPstep

トップページ > PHPで占いプログラムを作ろう >

第二章 PHPでウェブアプリケーションを作ろう

PHPで占いプログラムを作ろう4

PHPで占いプログラムを作ろう」の第4回です。 第3回までで生年月日入力ページ(index.php)が完成しました。 第4回からは送信されたデータを受け取って、占いの鑑定結果を表示するページ(result.php)を作っていきます。
※最終完成形はこちら→占いプログラムサンプル

鑑定結果表示ページ(result.php)で行う処理の流れ

これから作成していく鑑定結果表示ページ(result.php)は、 ユーザーの入力した生年月日を元に、星座を算出して、占いの鑑定結果を表示するページです。 おおまかに下記のような流れで一連の処理をします。

  1. ユーザーが入力した生年月日のデータを受け取ります。
  2. 入力された年月日が存在するかどうか妥当性をチェックをします。
  3. ユーザーの入力した年月日が妥当な場合には、月と日から星座を算出します。
  4. 各星座に対応した鑑定文とイラスト画像を表示します。

入力された年月日の妥当性をチェックする

テキストエディタのメニューから[ファイル]→[新規作成]と選択して、新しいファイルを作成します。 [ファイル]→[名前を付けて保存]を選択して、「result.php」というファイル名で新規保存してください。

いま新規作成したresult.phpに下記の内容を記述してください。

サンプルソース:result.php
<?php //変数の受け取り extract($_GET); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ねこ占い鑑定結果|生年月日を元にした占いプログラム</title> </head> <body> <h1>ねこ占い</h1> <?php /******************************* 未入力チェック *******************************/ $errmsg = ''; //エラーメッセージを空にしておく if ($y == '') { $errmsg = $errmsg.'<p>生まれた年が入力されていません。</p>'; } if ($m == '') { $errmsg = $errmsg.'<p>生まれた月が入力されていません。</p>'; } if ($d == '') { $errmsg = $errmsg.'<p>生まれた日が入力されていません。</p>'; } /******************************* 年月日の妥当性チェック *******************************/ if ($errmsg == '') { if (!checkdate($m, $d, $y)) { $errmsg = $errmsg.'<p>入力された年月日は存在していません。</p>'; } } /******************************* 鑑定結果の表示 *******************************/ if ($errmsg != '') { //エラーメッセージが空ではない場合には、エラーメッセージを表示する echo $errmsg; echo '<p><a href="javascript:history.back();">前のページへ戻る</a></p>'; } else { echo '<p>'.$y.'年'.$m.'月'.$d.'日生まれ</p>'; } ?> </body> </html>

入力が完了したら、result.phpを上書き保存してください。

ブラウザで表示確認してみよう

いま上書き保存したindex.phpをブラウザで表示確認してみましょう。

XAMPPによる動作確認手順
  1. XAMPPのコントロールパネルを立ち上げて、コントロールパネルの中のApacheをStartさせます。
  2. ブラウザのアドレス欄に http://localhost/sample/fortune/ と入力して、生年月日入力ページを表示させます。
  3. 適当に生年月日を選択して、[生年月日で占う!]ボタンを押します。
  4. 2月31日のような存在しない日付を選択して、[生年月日で占う!]ボタンを押します。

例えば、「2000年2月2日」などの年月日を入力すると、「2000年2月2日生まれ」という具合に生年月日が表示されるはずです。 そして、「2000年2月31日」のような存在しない年月日を入力した場合には、 下記のように「入力された年月日は存在していません。」と表示されれば成功です。



extract()関数で変数を受け取る

PHPソースをいくつかの部分に分けて、順番に確認していきましょう。 まず、ソースの先頭に記述した変数の受け取り部分に注目してみましょう。

サンプルソース:result.phpの抜粋
<?php //変数の受け取り extract($_GET); ?>

上記のPHPソースではextract()という関数を使用して、前のページから送信されたデータを受け取っています。 extract()は、配列から値を抽出してそれぞれを変数に代入してくれる大変便利な関数です。 extract($_GET)と指定すると、フォームで送信された複数の値をまとめて変数に代入することができます。

コラム「extract()関数は危ない?」

extract()は、配列から値を抽出してそれぞれを変数に代入してくれる大変便利な関数です。 例えば、フォームで送信された複数のデータを受信する際、 ひとつひとつ受け取らなくてもextract($_GET)、あるいは、extract($__POST)と記述すればまとめて変数に代入できます。 そのため、プログラムソースを短くでき、データの受け取り忘れもなくせます。

ただし、このextract()関数は、使い方を誤るとセキュリティ面で問題が起きる場合があるので注意が必要です。 プログラム中ですでに変数に値が代入されている場合、その後にextract()関数を使用するとその変数の値が上書きされます。 制作者としては、ある変数の値をページ間で受け渡さないプログラムにしているつもりでも、 悪意を持ったユーザーが故意にその変数の値を送信した場合、制作者にとっては予期しない動作になってしまう可能性があります。

今回作成しているのはお遊びの占いプログラムですので、仮に誤動作を起こしても深刻な問題にはならないと考え、 少し横着をしてextract($_GET);でデータをまとめて変数に代入することにしました。 また、どの変数にもデータの代入を行っていないresult.phpの先頭部分でextract()関数を使用しているので、 既存のデータの上書きは起こらないと判断しました。

ちなみに、extract()関数を使用することによるセキュリティ面の不安を避けたい場合、 extract($_GET);のデータ受け取り部分のソースを下記のように記述しても良いでしょう。

サンプルソース:result.phpの記述例
<?php //変数の受け取り $y = $_GET["y"]; //年 $m = $_GET["n"]; //月 $d = $_GET["d"]; //日 ?>

上記のように変数ごとに値を代入してやれば、extract()関数によって予期せぬ値の上書きが起きる可能性を無くせます。

未入力チェック部分のソースを確認しよう

次に、未入力チェックと年月日の妥当性チェック部分のPHPソースに注目してみましょう。

サンプルソース:result.phpの抜粋
<?php /******************************* 未入力チェック *******************************/ $errmsg = ''; //エラーメッセージを空にしておく if ($y == '') { $errmsg = $errmsg.'<p>生まれた年が入力されていません。</p>'; } if ($m == '') { $errmsg = $errmsg.'<p>生まれた月が入力されていません。</p>'; } if ($d == '') { $errmsg = $errmsg.'<p>生まれた日が入力されていません。</p>'; } /******************************* 年月日の妥当性チェック *******************************/ if ($errmsg == '') { if (!checkdate($m, $d, $y)) { $errmsg = $errmsg.'<p>入力された年月日は存在していません。</p>'; } } /******************************* 鑑定結果の表示 *******************************/ if ($errmsg != '') { //エラーメッセージが空ではない場合には、エラーメッセージを表示する echo $errmsg; echo '<p><a href="javascript:history.back();">前のページへ戻る</a></p>'; } else { echo '<p>'.$y.'年'.$m.'月'.$d.'日生まれ</p>'; } ?>

未入力チェックの部分では、年・月・日についてそれぞれ未入力項目があった場合に変数$errmsgにエラーメッセージを代入しています。 そして、鑑定結果の表示部分では、変数$errmsgが空ではない場合にはエラーメッセージを表示して、 変数$errmsgが空の場合には何年何月何日生まれかを表示しています。

未入力チェック機能については、「PHPでメール送信フォームを作ろう」の 第5回「未入力チェック機能をつくる」、 第6回「未入力チェック機能を洗練させる」 で作った機能とほぼ同じですので参考にしてください。

妥当性チェック部分のソースを確認しよう

続いて、年月日の妥当性チェックの部分に注目してみます。

サンプルソース:result.phpの抜粋
<?php /******************************* 未入力チェック *******************************/ $errmsg = ''; //エラーメッセージを空にしておく if ($y == '') { $errmsg = $errmsg.'<p>生まれた年が入力されていません。</p>'; } if ($m == '') { $errmsg = $errmsg.'<p>生まれた月が入力されていません。</p>'; } if ($d == '') { $errmsg = $errmsg.'<p>生まれた日が入力されていません。</p>'; } /******************************* 年月日の妥当性チェック *******************************/ if ($errmsg == '') { if (!checkdate($m, $d, $y)) { $errmsg = $errmsg.'<p>入力された年月日は存在していません。</p>'; } } /******************************* 鑑定結果の表示 *******************************/ if ($errmsg != '') { //エラーメッセージが空ではない場合には、エラーメッセージを表示する echo $errmsg; echo '<p><a href="javascript:history.back();">前のページへ戻る</a></p>'; } else { echo '<p>'.$y.'年'.$m.'月'.$d.'日生まれ</p>'; } ?>

妥当性チェックの部分では、checkdate()という関数を使用しています。 PHPのcheckdate()関数では、グレゴリオ暦の日付/時刻として妥当かどうかが確認されます。 上記のソースでいうと checkdate($m, $d, $y) の部分で、入力された年月日が存在する日付かどうかをチェックしています。

その外側に掛けられている if ($errmsg == '') {} というif文は、年・月・日のそれぞれの値が揃っているかどうかを判別しています。 これは、変数$m・$d・$yの値が空のままcheckdate()関数を使用するとエラーが発生するためです。 つまり、年・月・日のそれぞれの値が揃っている場合に限り、checkdate()関数による日付の妥当性チェックをするということです。