PR

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のWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

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