今までのオブジェクト指向までの学習ではwebページにPHPプログラムを埋め込み、サーバー側で処理した結果をブラウザへ表示するだけの、いわば一方通行のデータ送信でした。今回からブラウザからサーバーにデータを送信し、それに対して応答、プログラムの処理を行うということを学習します。まず手始めにGETメソッドとPOSTメソッドを見ていきましょう。
スーパーグローバル変数でリクエスト情報を取得する
HTTP通信というわけで、ブラウザから送られるリクエスト情報をPHPプログラムで解析するわけですが、その場合スーパーグローバル変数というものを使います。ちなみにスーパーグローバル変数には以下があります。
スーパーグローバル変数名 | 内容 |
$_GET | GETメソッドによって渡されるクエリ情報 URLパラメーターとして渡されるデータ |
$_POST | POSTメソッドによってHTMLから渡された情報。 |
$_FILES | POSTメソッドで渡されたファイルの情報 |
$_COOKIE | クッキー経由で渡された情報 |
$_SESSION | セッションに関する情報 |
$_REQUEST | $_POST, $_GET, $COOKIEをまとめて管理された情報 |
$_ENV | サーバー側で定義した環境変数 |
簡単に内容を説明しましたが、それぞれPHP側からリクエストの情報を操作するためのもので、ブラウザから渡された情報を解析し、内部的に自動で用意されます。スーパーなグローバルな変数なのでプログラムのどこからでもアクセスできます。全部1記事にまとめると長くなるので回を分けて説明していきます。今回はタイトル通りGETメソッドとPOSTメソッドを説明します。
GETメソッドでクエリ送信、処理
amazonなどのwebページを開いた時商品名を検索するとURLがすごく長くなったりしますね。言語は違ってきますが、概念は同じです。よく見ると~~?とあり、その後ろに〇〇=〇〇となっているのがわかります。これはキー名=値が付加されており、これをクエリパラメータと呼びます。クエリとはデータの問い合わせや要求などを意味しており、複数のクエリパラメータを&でくっつけてクエリ情報としてまとめて送信しています。キー名はそれぞれのwebサイトで決めており、アマゾンだと「s?k」だったり「__mk_ja_JP」と指定しています。
データの送信画面を作る
webページからデータを送信する画面を作成してみましょう。
<!DOCTYPE html>
<html>
<body>
<form method="GET" action="response.php">
NAME:
<input type="text" name="name" />
<input type="submit" value="送信"/>
</form>
</body>
</html>
続いて送信されたデータを処理するプログラムを作成します。
<!DOCTYPE html>
<html>
<body>
Hello, <?php print $_GET['name']; ?>.
</body>
</html>
send.phpでform要素でmethod属性をGETにし、action属性に送信先のファイルのURLを指定しています。今回は同階層にファイルを保存しているのでファイル名だけ記述しています。テキストフィールドの名前をnameにしているのでキー名がnameとなり、値がinputフィールドで入力された値になります。そのキー名と値のペアが送信されたので、処理するプログラムの方では$_GETでキー名のnameを指定して取り出しています。
URLを見るとキー名になったnameと値が表示されているのがわかるでしょうか。GETメソッドはこのようにURLにクエリ情報が表示されます。
htmlspecialchars()でクロスサイトスクリプティング対策
攻撃手法にクロスサイトスクリプティングというものがあり、web掲示板やtwitterのような入力内容をWebページに表示するWebアプリケーションにおいて、悪意のあるスクリプト付きのリンク貼ったり等、ターゲットに注入し、閲覧者に送信する攻撃です。これによりカード情報や名前、住所などの個人情報を抜き取ります。
その対策に、ユーザーが入力した値を表示する場合はHTMLエスケープという処理を行う必要があります。「<」や「>」などの特別な文字をエスケープ処理するのです。そのエスケープ処理を行う関数があります。
その関数がhtmlspecialchars()です。詳しい構文などについてはリファレンスを読むと分かりやすいです。
実際に使用して表示してみましょう。
<?php
function esc($str, $charset = 'UTF-8') {
print htmlspecialchars($str, ENT_QUOTES, $charset);
}
?>
作成したEsc.phpを読み込んでesc関数を使用して名前を表示してみましょう。
<!DOCTYPE html>
<html>
<body>
<?php require_once 'Esc.php'; ?>
Hello, <?php print esc($_GET['name']); ?>.
</body>
</html>
このようにhtmlspecialchars関数を使用して表示すればクロスサイトスクリプティング対策になります。
POSTメソッドでデータ送信、処理結果を返す
今度はPOSTメソッドを用いてデータを送信して、処理して返します。POSTメソッドで送信されるデータのことをポストデータと呼びます。ポストデータはGETメソッドと違いデータがアドレス欄に表示されません。基本的には単にデータを取得するだけならGET、それ以外の何らかの情報を変更させるなどの処理ではPOSTを使うようにします。
<!DOCTYPE html>
<html>
<body>
<form method="POST" action="response.php">
NAME:
<input type="text" name="name" />
<input type="submit" value="送信"/>
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<?php require_once 'Esc.php'; ?>
Hello, <?php print esc($_POST['name']); ?>.
</body>
</html>
GETをPOSTに変換しただけですが、アドレスを見るとGETと違いパラメータが表示されていませんね。
GETとPOSTのリクエスト情報の違い
2つの違いをはっきり覚えておきましょう。
- クエリ情報はURLに付加され、ポストデータはリクエストボディに格納されて送信されます。
- クエリ情報はURLの末尾に追加されるので丸見えです。
- クエリ情報はブックマーク保存でき、ブックマークから直接検索結果などのページを表示できます。
フォーム以外からクエリ情報を追加して送信
リンク先を指定する際に、href属性で末尾に?を記述した後に続いてクエリ情報を記述します。クエリ情報はキー名=値の形式でしたね。
<!DOCTYPE html>
<html>
<body>
<!-- urlencode()関数を使用してURLエンコードを行う必要がある。-->
<a href="response.php?q=<?php print urlencode('クエリ情報'); ?>">送信</a>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<?php require_once 'Esc.php'; ?>
<?php esc($_GET['q']); ?>
</body>
</html>
リンクを踏むと、「&#クエリ情報」と表示されましたね。このようにフォーム以外からクエリ情報を送信する際はこのようにクエリ情報をリンクに付加します。
コメント