Webフォームを使ってデータを送る(GETリクエスト)
利用者がデータを送る際に、その内容を(URLエンコードで)URLに書き加えてくれというのは難しい注文ですよね。そのために用意されているものが、Webフォームです。誰でも一度は触ったことがあるでしょう。
図3:ブラウザで見たWebフォーム
HTMLソース
<form method="GET" action="profile.php">
名前:<input type="text" name="name" value="John"><br>
年齢:<input type="text" name="age" value="25"><br>
性別:<label><input type="radio" name="sex" value="male" checked>男</label>
<label><input type="radio" name="sex" value="female">女</label><br>
趣味:<label><input type="checkbox" name="hobbies[]" value="cooking" checked>料理</label>
<label><input type="checkbox" name="hobbies[]" value="swimming" checked>水泳</label>
<label><input type="checkbox" name="hobbies[]" value="running">ランニング</label><br>
住所:<select name="address">
<option value="north">北日本</option>
<option value="east" selected>東日本</option>
<option value="west">西日本</option>
<option value="south">南日本</option>
</select><br>
コメント:<textarea type="text" name="comment">Hello</textarea><br>
<br>
<input type="submit" value="送信">
</form>
submitボタンを押すと、そのボタンが含まれているformタグの中にあるすべての入力フォーム(input、selectタグなど)のデータが送信されます。送信先はformタグのaction属性で指定したURLで、このときに使われるHTTPリクエストをmethod属性に指定します。それぞれのフォーム要素のname属性がキーになります。
つまり、入力フォームにデータを入力して送信ボタンを押すと、ブラウザが自動的に次のようなリクエストを送信するのです。これならば、利用者が自分でURLを作る必要がありませんよね。
GET http://example.jp/profile.php?name=John&age=25&sex=male&hobbies[]=cooking&hobbies[]=swimming&address=east&comment=Hello
ここでの1つ目のポイントは、チェックボックスで入力する「趣味」の項目です。このフォームの name 属性は「hobbies[]」とカッコが付いていて、同じキーが複数あります。これは、PHPの配列の書き方と似ていますよね。そうです、趣味は複数選ぶことができるので、選択したものが配列に入るのです。
<?php
var_dump($_GET["hobbies"]); // ※キー名に [] は不要です
// array(2) {
// [0]=>
// string(7) "cooking"
// [1]=>
// string(8) "swimming"
// }
?>
もう1つのポイントは、このように送信されてきたデータはすべて「文字列型」になっているということです。年齢は数字で入力しますが、数値型ではなく文字列型の数字で送られてきます。このことは、後述する「検証」のところで関係してきます。
<?php
var_dump($_GET["name"]); // string(4) "John"
var_dump($_GET["age"]); // string(2) "25"
// 参考までに…
var_dump(25); // int(25)
var_dump("25"); // string(2) "25"
?>
Webフォームを使ってデータを送る(POSTリクエスト)
ところで、URLに情報を乗せたくない場合や、情報が多すぎて乗せ切れない(Internet ExplorerではURLに2000文字程度までしか使えない)こともあります。そのようなときは、GETリクエストではなく、POSTリクエストを使います。
<form method="POST" action="profile.php">
名前:<input type="text" name="name" value="John"><br>
年齢:<input type="text" name="age" value="25"><br>
性別:<label><input type="radio" name="sex" value="male" checked>男</label>
<label><input type="radio" name="sex" value="female">女</label><br>
趣味:<label><input type="checkbox" name="hobbies[]" value="cooking" checked>料理</label>
<label><input type="checkbox" name="hobbies[]" value="swimming" checked>水泳</label>
<label><input type="checkbox" name="hobbies[]" value="running">ランニング</label><br>
住所:<select name="address">
<option value="north">北日本</option>
<option value="east" selected>東日本</option>
<option value="west">西日本</option>
<option value="south">南日本</option>
</select><br>
コメント:<textarea type="text" name="comment">Hello</textarea><br>
<br>
<input type="submit" value="送信">
</form>
formのmethodをPOSTにすると、ブラウザは以下のようなリクエストを送信します。POSTパラメータは、URLには含まれない形でサーバに送られます。
POST http://example.jp/profile.php
POSTパラメータ
name John
age 25
...
PHPではPOSTパラメータを取得するには、$_POSTというグローバル変数を使います。
<?php
echo $_POST["name"]; // John
echo $_POST["age"]; // 19
echo $_POST["comment"]; // Hello
?>
POSTリクエスト時に 、併せてGETパラメータを付けることもできます。
POST http://example.jp/profile.php?design=sky
POSTパラメータ
name John
age 25
...
<?php
echo $_GET["design"]; // sky
echo $_POST["name"]; // John
?>
受け取ったデータを表示する
利用者からデータを受け取る方法が分かりましたので、今度は受け取ったデータを画面に表示するプログラムを書きましょう。WebフォームはPOST送信を使うことにします。
図4:POSTで受け取ったデータを画面に表示する(クリックで拡大)
Webフォームを出力しているのも、プロフィール画面を出力しているのも、同じ profile.php のプログラムです。つまり、条件によって別の画面を表示する必要があります。プログラム側の処理の流れは図5のようになります。
図5:条件によって出力する画面が異なる
図5にしたがって、プログラムの内容を書き出すと、以下のようになります。
- 1回目のアクセスの場合 → Webフォームを表示する
- 2回目以降のアクセスの場合
- すべてのデータが適切かどうかチェックする
- 適切でないデータがある場合 → エラーメッセージと再入力用のWebフォームを表示する
- すべてのデータが適切である場合 → データを画面に表示する
これらをひとつずつ見てみましょう。
(1)1回目のアクセスの場合
それではまず、初回表示かどうかを判断しましょう。初回表示というのは、まだ何もデータが送られて来ていない状態です。つまり、$_POST["name"]、$_POST["age"]、$_POST["sex"]、$_POST["hobbies"]、$_POST["address"]、$_POST["comment"]のどれかの値が取得できたら、2回目以降のアクセスということになります。しかし、いちいち全部の値を調べるのは面倒です。また、入力項目の種類や名前が今後変わるかもしれませんし、その際にまた書き直すのも大変です。というわけで、初回表示かどうかを判断するための項目をWebフォームに追加しましょう。画面上には表示されないhiddenタイプのinput要素を使います(送信ボタンにname属性を付ける方法もありますが、初回表示のチェック専用の要素を用意しておくほうが、汎用性が高くなります)。
<form method="POST" action="profile.php">
名前:<input type="text" name="name" value="John"><br>
年齢:<input type="text" name="age" value="25"><br>
性別:<label><input type="radio" name="sex" value="male" checked>男</label>
<label><input type="radio" name="sex" value="female">女</label><br>
趣味:<label><input type="checkbox" name="hobbies[]" value="cooking" checked>料理</label>
<label><input type="checkbox" name="hobbies[]" value="swimming" checked>水泳</label>
<label><input type="checkbox" name="hobbies[]" value="running">ランニング</label><br>
住所:<select name="address">
<option value="north">北日本</option>
<option value="east" selected>東日本</option>
<option value="west">西日本</option>
<option value="south">南日本</option>
</select><br>
コメント:<textarea type="text" name="comment">Hello</textarea><br>
<br>
<input type="hidden" name="not_the_first_time" value="yes">
<input type="submit" value="送信">
</form>
こうすると、1回目のアクセスでは $_POST["not_the_first_time"] は存在しませんが、送信ボタンを押されてアクセスしてくる2回目以降のアクセスでは、$_POST["not_the_first_time"] が存在しています。配列の中に、あるキーが存在するかどうかを調べるには、array_key_existsというPHPの関数を使います。
<?php
/*------------------------------------------------------------
2回目以降のアクセス
------------------------------------------------------------*/
if (array_key_exists("not_the_first_time", $_POST)) {
// 2回目以降はtrue
}
/*------------------------------------------------------------
1回目のアクセス
------------------------------------------------------------*/
else {
// 1回目はfalse
echo '
<form method="POST" action="profile.php">
名前:<input type="text" name="name" value="John"><br>
年齢:<input type="text" name="age" value="25"><br>
性別:<label><input type="radio" name="sex" value="male" checked>男</label>
<label><input type="radio" name="sex" value="female">女</label><br>
趣味:<label><input type="checkbox" name="hobbies[]" value="cooking" checked>料理</label>
<label><input type="checkbox" name="hobbies[]" value="swimming" checked>水泳</label>
<label><input type="checkbox" name="hobbies[]" value="running">ランニング</label><br>
住所:<select name="address">
<option value="north">北日本</option>
<option value="east" selected>東日本</option>
<option value="west">西日本</option>
<option value="south">南日本</option>
</select><br>
コメント:<textarea type="text" name="comment">Hello</textarea><br>
<br>
<input type="hidden" name="not_the_first_time" value="yes">
<input type="submit" value="送信">
</form>
';
}
?>