PHP - WEB - 7. HTTPリクエストの実践

引き続きHTTPリクエストについて見ていきましょう。

一般的にWebブラウザから送信されるHTTPリクエストには、GETリクエストとPOSTリクエストに分類されます。リンクをクリックしたり、アドレスバーからURLを入力したり、お気に入りのページを開いたり、Webブラウザ上で行うほとんどの操作はGETリクエストを送信します。 その中で例外的に form タグの method 属性に post と指定して送信ボタン( <input type="submit"> )をクリックしたときはPOSTリクエストを送信します。

ただしJavaScriptを使う場合はGETリクエスト、POSTリクエストの送信を自由にカスタマイズできます。

PHPプログラムの開発(名前検索プログラム)

ここではGETリクエストを使った簡単な名前検索プログラムを作成します。まずは検索結果として画面に表示するデータを準備しましょう。テキストエディタを開いて次のファイル( names.txt )を準備します。

Andy
Betty
Carol
Daniel

names.txt ファイルは以前に作成したものを再利用します。

この4件のデータを対象に画面から入力された名前を照合するようにします。たとえば画面から「Andy」という名前が送信された場合は4人の名前の中から「Andy」だけが対象として出力されるようにします。また「a」のように名前の一部が送信された場合は、Carol、Danielの2人が対象として出力されるようにします。

続いて検索画面( search.html )と検索キーワードを処理するプログラム( search.php )を作成します。まずは検索画面( search.html )から作成していきましょう。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>PHP Sample</title>
</head>
<body>
    <h3>Search</h3>
    <hr>
    <form action="search.php" method="get">
        <input type="text" name="name">
        <input type="submit" value="search">
    </form>
</body>
</html>

このプログラムでは form タグを使って検索キーワードを入力するフォームを定義しています。 form タグの action 属性に search.phpmethod 属性に get を指定します。また form タグの中にはテキストボックスと送信ボタンを定義しています。テキストボックスの name 属性の値である name はリクエストパラメータのキーになります。

続いて検索キーワードを処理するプログラム( search.php )を作成しましょう。

<?php
$name = $_GET["name"];
$names = file("names.txt", FILE_IGNORE_NEW_LINES);
$searched_names = [];
if ($name !== "") {
  for ($i = 0; $i < count($names); $i++) {
    if (strpos($names[$i], $name) !== false) {
      $searched_names[] = $names[$i];
    }
  }
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>PHP Sample</title>
</head>
<body>
  <h3>Search</h3>
  <hr>
  <ul>
  <?php
    for ($i = 0; $i < count($searched_names); $i++) {
  ?>
    <li><?php echo $searched_names[$i]; ?></li>
  <?php
    }
  ?>
  </ul>
</body>
</html>

このプログラムでは先頭部分で $_GET 変数を使ってクエリパラメータの name を取得しています。

$name = $_GET["name"];

この結果、 $name 変数 には画面で入力された名前が代入されます。

次に file 関数で names.txt のレコードを配列に置き換えています。

$names = file("names.txt", FILE_IGNORE_NEW_LINES);

$names 変数には 配列データ ["Andy", "Betty", "Carol", "Daniel"] が代入されます。

PHPプログラムの残りの部分も見てみましょう。

$searched_names = [];
if ($name !== "") {
  for ($i = 0; $i < count($names); $i++) {
    if (strpos($names[$i], $name) !== false) {
      $searched_names[] = $names[$i];
    }
  }
}

このプログラムでは $searched_names 変数に初期値として空の配列データを代入しています。その後、 if 文で $name 変数が空文字でないことを確認した後、 for 文を使って $names 配列の要素を順に処理しています。 for 文の繰り返し処理においては strpos 関数を使って画面から入力された文字列データを含む名前を探しています。この結果、 $searched_names 配列には検索キーワードを含む名前だけが代入されるようになります。

strpos 関数は、文字列内の部分文字列が最初に現れる場所を見つけるための関数です。部分文字列が存在しない場合は false を返します。 https://www.php.net/manual/ja/function.strpos.php

それではビルトインWebサーバを起動して実際にプログラムにアクセスしてみましょう。

$ php -S localhost:8080

続いてWebブラウザから search.html にアクセスします。アドレスバーに以下のURLを入力します。

https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/search.html

表示された検索画面において Andy と入力して送信ボタンをクリックしてみましょう。

そうすると次のような検索結果が表示されるでしょう。

ここではアドレスバーに表示されているURLについても注目してください。

https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/search.php?name=Andy

このようにGETリクエストの場合はこのようにURLの一部にリクエストパラメータが付与されます。

もう少し動作確認をしてみましょう。ブラウザの「戻る」ボタンを押して検索画面に戻り、次は名前に"a"と入力して送信ボタンをクリックしてみましょう。

そうすると次のような検索結果が表示されるでしょう。

アドレスバーに表示されているURLについても確認しておきましょう。

https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/search.php?name=a

画面から入力された名前「a」がURLの一部に含まれていることがわかります。

クエリパラメータの利用

GETリクエストで送信されるリクエストパラメータはURLの一部としてWebサーバに送信されます。このようなリクエストパラメータはクエリパラメータ、クエリストリングなどと呼びます。

このクエリパラメータは form タグだけでなく a タグに利用することもできます。たとえば次のような a タグを考えてみましょう。

<a href="search.php?name=a">Search: a</a>

この a タグは画面に表示すると「 Search: a 」というリンクが表示されますが、実際にクリックすると次のURLへのリクエストになります。

https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/search.php?name=a

上記のURLはよく見ると、さきほど「a」という名前で送信ボタンをクリックしたときのURLと同じです。つまり a タグで作成するリンクにもクエリパラメータを指定することができるのです。

それでは実際にプログラムを作成してみましょう。さきほどの検索画面( search.html )にクエリパラメータを送信するリンクを追加してみましょう。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>PHP Sample</title>
</head>
<body>
    <h3>Search</h3>
    <hr>
    <form action="search.php" method="get">
        <input type="text" name="name">
        <input type="submit" value="search">
    </form>
    <a href="search.php?name=a">Search: a</a>
</body>
</html>

ここでは form タグの後に a タグを追加しています。 a タグの href 属性には search.php?name=a としています。

プログラムの修正は以上です。ビルトインWebサーバが起動していることを確認してWebブラウザから検索画面にアクセスしてみましょう。

https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/search.html

表示された画面には「Search: a」というリンクが表示されているので、リンクをクリックしてみましょう。そうするとさきほどの検索結果と同じ内容が表示されるでしょう。

このようにGETリクエストのクエリパラメータはURLの一部として機能します。そのため a タグの href 属性にもクエリパラメータを含むURLを指定することが可能です。このようにクエリパラメータの利点は再利用できるという点です。これまでに見てきたように、以下のURLは「a」という名前で検索した結果を意味します。

https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/search.php?name=a

それではアドレスバーから直接上記のURLを入力するとどうなるのでしょうか。実際に試してみると、検索画面から送信ボタンをクリックすることなく検索結果にアクセスできます。これはGETリクエスト(クエリパラメータ)の大きな特徴です。検索結果を表すURLが再利用できるので、たとえばお気に入りに登録することもできます。

一方、POSTリクエストで検索画面を実装した場合はリクエストパラメータはボディパートに格納されているためURLの一部に含まれません。そのためアドレスバーから直接URLを指定した場合もリクエストパラメータが不足してしまうため正しく動作しません。POSTリクエストは本来、Webサーバ上にリソースを作成する用途に利用するため、何度も繰り返しリクエストパラメータが送信できてしまうと問題になるケースが多いからです。

まとめ

  • フォームの送信、リンクのクリック、アドレスバーの入力などでHTTPリクエストは発生する
  • フォームのPOST送信時以外のリクエストは原則GETリクエストとなる
  • リンクのURLにもクエリパラメータを付与できる