第15章 WEB対応

GETとPOSTリクエスト

PHPでは、主にHTTP GETリクエストとHTTP POSTリクエストを使ってクライアントからサーバーへの情報伝達が行われます。それぞれのリクエストは特定の目的と使用場面があり、それぞれに適した使い方があります。


GETリクエスト

GETリクエストは、特定のリソース(通常はHTMLドキュメント)をサーバーから要求する際に使用されます。GETリクエストは情報を取得するためのもので、サーバーの状態を変更すべきではありません(これをHTTPの「安全なメソッド」が保証します)。

GETリクエストには情報(パラメータ)を付加することができ、その情報はURLの一部として送られます。以下はその例です。

// クライアントからのGETリクエストを扱う
$name = $_GET["name"];  // URLに含まれる"name"パラメータを取得
echo "Hello, " . htmlspecialchars($name);

上記のスクリプトは、http://example.com/?name=JohnのようなURLに対するリクエストを処理します。この場合、出力は"Hello, John"になります。

ただし、GETリクエストには長いデータを送ることができず、またURLに情報が含まれるためセキュリティ上の観点から機密情報を送信するには不適切です。


POSTリクエスト

POSTリクエストは、クライアントからサーバーへ情報(データ)を送信するために使用されます。例えば、フォームのデータをサーバーへ送信したり、データベースに新しいレコードを作成したりする際にはPOSTリクエストが使用されます。

POSTリクエストのデータはリクエストボディに含まれており、長いデータやバイナリデータ(ファイルなど)の送信にも対応しています。以下はその例です。

// クライアントからのPOSTリクエストを扱う
$name = $_POST["name"];  // リクエストボディの"name"パラメータを取得
echo "Hello, " . htmlspecialchars($name);

上記のスクリプトは、POSTリクエストと共に送信されたフォームデータを処理します。この場合、ユーザーがフォームに"John"と入力したとすると、出力は"Hello, John"になります。

POSTリクエストは、GETリクエストと比較してよりセキュアな方法でデータを送信することが可能です。ただし、適切なセキュリティ対策(例えばCSRFトークン)がないと、セキュリティ上のリスクがあります。


クッキーとセッション

クッキーとセッションは、PHPでウェブアプリケーションを開発する際に非常に重要な役割を果たします。これらはどちらも、状態を保持するための仕組みで、HTTPが基本的にはステートレスなプロトコルであるため、特定のユーザーの情報を保持するために使用されます。


クッキー (Cookies)

クッキーは、ブラウザによってユーザーのコンピューターに保存される小さなテキストファイルです。これらは、ウェブサイトがユーザーを記憶し、そのユーザーの以前の活動を追跡するのに役立ちます。

以下に、PHPでクッキーを設定する例を示します。

setcookie("user", "John Doe", time()+3600);  // 1時間後に有効期限が切れるクッキーを設定

この例では、userという名前のクッキーを設定し、その値をJohn Doeとしています。また、このクッキーの有効期限を現在時刻から1時間後(time()+3600)に設定しています。

クッキーは、ブラウザが閉じられても保存され続けます。ただし、クッキーはユーザーによっていつでも削除することが可能で、またブラウザの設定でクッキーを受け入れないようにすることも可能です。


セッション (Sessions)

セッションは、サーバー上でユーザー情報を一時的に保持するための仕組みです。セッションは、ユーザーがブラウザを閉じるか、明示的にセッションを破棄すると終了します。

以下に、PHPでセッションを開始し、セッション変数を設定する例を示します。

session_start();  // セッションを開始
$_SESSION["user"] = "John Doe";  // セッション変数を設定

この例では、まずsession_start関数を使用してセッションを開始します。そして、$_SESSIONというスーパーグローバル配列を使用して、セッション変数userを設定し、その値をJohn Doeとしています。

セッションはサーバー上に保存されるため、大量のデータを保存することが可能です。また、クッキーよりもセキュリティが高いとされています。しかし、セッションは一時的なものであり、永続的なデータ保持には適していません。


レスポンスヘッダとステータスコード

PHPでウェブアプリケーションを開発する際には、HTTPのレスポンスヘッダとステータスコードの扱い方を理解することが重要です。以下にその基本的な知識について説明します。


レスポンスヘッダ

レスポンスヘッダは、サーバーからクライアントに送信されるメタデータを含む情報です。これには、コンテンツタイプ、エンコーディング、クッキー、キャッシュコントロールなどの情報が含まれます。

PHPでは、header()関数を使用してレスポンスヘッダを設定できます。この関数は、ヘッダが送信される前(すなわち、出力が開始される前)に呼び出さなければなりません。

以下は、PHPでレスポンスヘッダを設定する例です。

header("Content-Type: text/plain");  // コンテンツタイプをテキストプレーンに設定


ステータスコード

HTTPステータスコードは、サーバーがクライアントのリクエストをどのように処理したかを示す3桁の数字です。たとえば、200はリクエストが正常に処理されたことを示し、404はリクエストしたリソースが見つからなかったことを示します。

PHPでもheader()関数を使用してステータスコードを設定できます。

以下は、PHPでステータスコードを設定する例です。

header("HTTP/1.1 404 Not Found");  // ステータスコードを404に設定


サーバ環境情報

$_SERVERは、ヘッダー、パス、スクリプトの位置など、サーバー環境に関する情報を保持する配列です。以下に一部を紹介しますが、すべての環境で利用可能とは限りません。また、サーバの設定や実行環境により値が変わる可能性があります。

  1. $_SERVER['PHP_SELF']: 現在実行中のスクリプトのファイル名を含むパス。
  2. $_SERVER['REQUEST_METHOD']: ページにアクセスするために使用されたリクエストメソッド(例: POST, GET)。
  3. $_SERVER['REQUEST_TIME']: リクエストが開始された時刻。Unix タイムスタンプとして返されます。
  4. $_SERVER['QUERY_STRING']: URL のクエリ文字列(URL 中の ? 以降の部分)。
  5. $_SERVER['HTTP_REFERER']: ユーザエージェントにより設定された、現在のページへリンクする前のページのアドレス。
  6. $_SERVER['HTTP_USER_AGENT']: 現在のページにアクセスしているユーザエージェントの情報。
  7. $_SERVER['REMOTE_ADDR']: ページを見ているユーザの IP アドレス。
  8. $_SERVER['SCRIPT_URI']: 現在のページの URI。

これらの情報は、ブラウザからサーバーへのリクエスト中に利用でき、それぞれのページリクエストの情報を含んでいます。具体的な使い方としては、ユーザーの IP アドレスやブラウザ情報を取得したり、特定のリクエストメソッドが使用されているかどうかを判断したりするのに役立ちます。


URLリライティング

URLリライティングとは、ウェブアプリケーションが生成するURLの形式を自由に変更する技術のことを指します。PHPでは、Apacheのmod_rewriteモジュールやNginxのrewriteモジュールなどを使ってURLリライティングを行うことが多いです。

たとえば、下記のようなパラメータを含むURL

http://example.com/product.php?id=100

を以下のように"きれいなURL"(Clean URL)や"フレンドリーURL"(Friendly URL)に変換することがURLリライティングの一例です。

http://example.com/product/100

これをPHPとApacheを使って実現するには、.htaccessファイルを使ってリライティングのルールを設定します。以下に具体的な設定例を示します。

RewriteEngine On
RewriteRule ^product/([0-9]+)$ product.php?id=$1 [L]

この設定により、http://example.com/product/100へのリクエストは内部的にhttp://example.com/product.php?id=100へとリライティングされます。

PHP側では通常のGETパラメータとしてidを受け取ることができます。

$id = $_GET['id'];  // 100

URLリライティングを利用することで、URLが見やすくなり、ユーザーにとって親しみやすくなるだけでなく、SEO(検索エンジン最適化)にも寄与します。ただし、URLリライティングのルール設定はサーバの設定に依存するため、適切な知識と経験が必要です。


ファイルのアップロード

PHPでファイルをアップロードするには、まずHTMLのフォームでenctype="multipart/form-data"を指定し、<input type="file">要素を使ってユーザーにファイルを選択させます。

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="userfile">
    <input type="submit" value="アップロード">
</form>

次に、PHPでは$_FILESスーパーグローバル配列を使用してアップロードされたファイルにアクセスします。アップロードされたファイルは一時的なディレクトリに保存され、move_uploaded_file()関数を使って目的のディレクトリに移動します。

if ($_FILES['userfile']['error'] == UPLOAD_ERR_OK) {
    $uploadfile = '/path/to/upload/' . basename($_FILES['userfile']['name']);
    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
        echo "ファイルが正常にアップロードされました。\n";
    } else {
        echo "ファイルのアップロードに失敗しました。\n";
    }
} else {
    echo "ファイルのアップロードに問題が発生しました。\n";
}


ファイルのダウンロード

PHPでファイルをダウンロードするには、まずダウンロードしたいファイルのパスを特定します。次に、ヘッダーを使ってブラウザにダウンロードするファイルの情報を伝え、readfile()関数を使用してファイルの内容を出力します。

$file = '/path/to/download/file.txt';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

このコードは、ブラウザにfile.txtをダウンロードするように指示します。header()関数を使用して、ファイルの名前、タイプ、サイズなどの情報をブラウザに伝え、readfile()関数を使用してファイルの内容をブラウザに送信します。


レスポンスの種類

PHPは、様々な形式のレスポンスをクライアント(通常はWebブラウザ)に送信することができます。主なレスポンスの種類は以下の通りです。

  • HTML:Webページの表示に最も一般的に使用されるレスポンスの形式。PHPスクリプトは、HTMLを動的に生成し、それをブラウザに送信することができます。
  • JSON:PHPは、連想配列やオブジェクトをJSON形式にエンコードしてレスポンスとして送信することができます。これは主に、AjaxリクエストのレスポンスやRESTful APIのレスポンスとして使用されます。
  • $response = ['status' => 'success', 'message' => '操作が成功しました。'];
    header('Content-Type: application/json');
    echo json_encode($response);
    
  • XML:XMLもまた、データ交換のためのレスポンス形式として使用されることがあります。SimpleXMLやXMLWriterといったPHPのライブラリを使用してXMLを生成できます。
  • Plain Text:テキスト形式のレスポンスも可能で、主にデバッグや簡易的な情報伝達に使われます。Content-Type ヘッダを text/plain に設定します。
  • header('Content-Type: text/plain');
    echo "This is a plain text response.";
    
  • Binary Data:画像やPDFなどのバイナリデータもレスポンスとして送信できます。この場合、適切な Content-Type ヘッダを設定する必要があります(例: image/jpeg、application/pdf など)。
  • Redirect:PHPを使ってユーザーを別のURLにリダイレクトすることもできます。これは header() 関数を使って Location ヘッダを設定することで行います。
  • header('Location: https://www.example.com');
    exit;
    

それぞれのレスポンスの形式には適切な用途があり、必要に応じて適切な形式を選択することが重要です。


練習問題1.

名前と年齢をGETリクエストで受け取り、"Hello, my name is 〇〇 and I'm 〇〇 years old."と表示させるコードを書いてください。


練習問題2.

アクセスしたブラウザの情報を出力するコードを書いてください。


練習問題3.

セッションを開始し、セッション変数を設定し、訪問者の訪問回数をカウントし、"This is your nth visit."と表示するコードを書いてください。