Webフォーム:ブラウザからサーバにデータを送るためのしくみ

2015年3月24日(火)
野田 貴子

Webフォームを使ってデータを送る(GETリクエスト)

利用者がデータを送る際に、その内容を(URLエンコードで)URLに書き加えてくれというのは難しい注文ですよね。そのために用意されているものが、Webフォームです。誰でも一度は触ったことがあるでしょう。

ブラウザで見た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送信を使うことにします。

POSTで受け取ったデータを画面に表示する

図4:POSTで受け取ったデータを画面に表示する(クリックで拡大)

Webフォームを出力しているのも、プロフィール画面を出力しているのも、同じ profile.php のプログラムです。つまり、条件によって別の画面を表示する必要があります。プログラム側の処理の流れは図5のようになります。

条件によって出力する画面が異なる

図5:条件によって出力する画面が異なる

図5にしたがって、プログラムの内容を書き出すと、以下のようになります。

  1. 1回目のアクセスの場合 → Webフォームを表示する
  2. 2回目以降のアクセスの場合
  3. すべてのデータが適切かどうかチェックする
  4. 適切でないデータがある場合 → エラーメッセージと再入力用のWebフォームを表示する
  5. すべてのデータが適切である場合 → データを画面に表示する

これらをひとつずつ見てみましょう。

(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>
    ';
}
?>

1983年生まれ。大学卒業後、ソフトウェア開発の営業を経て、ソフトウェア開発業務に転向。現在は自社パッケージのフロントエンド開発のほか、PHPでの受託開発案件、日→英のローカライズ案件などを担当。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています