PHP - WEB - 11. セッション

それではセッションについて学習していきましょう。Webアプリケーションにおけるセッションとは、ユーザとの一連のやりとりを記録する仕組みです。HTTPの一つひとつのリクエスト・レスポンスはそれぞれ独立しているため、前回のリクエストを処理しているときにPHP上で参照していた変数を、次のリクエストを処理するときに参照することはできないようになっています。このような制約があるため、複数のリクエスト・レスポンスにまたがって処理を行うことが難しくなります。

具体的な例として、ショッピングサイトで商品を購入するケースを考えてみましょう。一般的なショッピングサイトであれば商品を検索して、商品ページに遷移して、ショッピングカートに商品を追加して、それから会計処理に進みます。これらの一つひとつの操作は、独立したHTTPリクエスト・レスポンスのやりとりです。そのため、これらの一連のやりとりで発生するデータを、通常のPHPの変数で保持しようとしても、会計処理までデータを持ち回ることができないのです。

そこで必要になるのがセッションという仕組みです。セッションとはWebアプリケーションのユーザ一人ひとりとのやりとりを記録する仕組みです。さきほどのショッピングサイトの例であれば、ショッピングカートに追加した商品をセッションに保存しておくことで、あとの会計処理の中でもショッピングカート内の商品データにアクセス可能となります。

セッションを利用するプログラム

それでは実際にセッションを操作するPHPプログラムについて見ていきましょう。PHPでセッションを利用するときは予め session_start 関数を呼び出しておく必要があります。

session_start();

上記のように session_start 関数を呼び出すことで $_SESSION 変数を利用できるようになります。この $_SESSION 変数はPHPの中に用意されている特別な変数です。この $_SESSION 変数は、連想配列のようにキーを指定して値を保存したり、キーを指定して値を取得したりすることができます。

// セッションに"id"キーで"Andy"を保存
$_SESSION["id"] = "Andy";
// セッションに"time"キーで現在日時を保存
$_SESSION["time"] = date("Y-m-d H:i:s");

上記のように $_SESSION 変数に保存したデータは、以降の別のリクエストを処理するPHPプログラムにおいても次のように取得できます。

// セッションから"id"キーで保存されている値を取得($nameに以前に保存した"Andy"が代入される)
$name = $_SESSION["id"];
// セッションから"time"キーで保存されている値を取得($timeに以前に保存した現在日時が代入される)
$time = $_SESSION["time"];

PHPプログラムの開発(ログイン処理)

ここでは以前に作成していたログイン画面を修正してセッションの動作を確認していきましょう。具体的に、ログイン処理( login.php )において、ログインに成功したユーザのIDと日時(ログイン日時)をセッションに保存するようにします。その後、リダイレクトによって呼び出されるメニュー画面の表示処理( menu.php )において、セッションからユーザIDとログイン日時を取得して、画面に表示します。

まず以前に作成したログイン画面( login.html )について確認しておきましょう。

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

ログイン画面( login.html )については特に変更はないので、以前作成していたものをそのまま利用することにします。

次にログイン処理( login.php )のプログラムを修正します。

<?php
$id = $_POST["id"];
$password = $_POST["password"];
if ($id === "Andy" && $password === "secret") {
  session_start();
  $_SESSION["id"] = $id;
  $_SESSION["time"] = date("Y-m-d H:i:s");

  header("location: menu.php");
} else {
  header("location: login.html");
}

このプログラムではログイン成功時に session_start 関数を呼び出してセッションを開始しています。

  session_start();

これによって以降のPHPプログラムの処理において $_SESSION 変数を利用できるようになります。

  $_SESSION["id"] = $id;
  $_SESSION["time"] = date("Y-m-d H:i:s");

$_SESSION 変数は連想配列のようにキーと値を指定して利用します。 ここでは $_SESSION 変数にリクエストから受け取った $id と、現在の日時( $time )を保存しています。

さいごにメニュー画面表示処理( menu.php )です。

<?php
session_start();
$id = $_SESSION["id"];
$time = $_SESSION["time"];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>PHP Sample</title>
</head>
<body>
  <h3>Menu - Hello <?php echo $id; ?></h3>
  <h5>Login at <?php echo $time; ?></h5>
  <hr>
  <ul>
    <li>ToDo</li>
  </ul>
</body>
</html>

このプログラムは login.php へのリクエストとは、異なる別のリクエストで呼び出されます。そのため login.php の中にある変数( $id$password )をこの menu.php の中で直接参照することができません。このような場合にセッションを使う必要があります。

プログラムの先頭部分を見てみましょう。

<?php
session_start();
$id = $_SESSION["id"];
$time = $_SESSION["time"];
?>

ここでもまず session_start 関数を呼び出しています。これによって $_SESSION 変数が利用できるようになります。 $_SESSION 変数には login.php にて保存した "id""time" といったキーが存在するので $id = $_SESSION["id"];$time = $_SESSION["time"]; のようにしてユーザID、ログイン日時を取得しています。

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

$ php -S localhost:8080

続いてWebブラウザからログイン画面( login.html )にアクセスします。アドレスバーに以下のURLを入力します。

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

次のようなログイン画面が表示されるでしょう。ここではIDに "Andy" 、パスワードに "secret" と入力してみましょう。

ログインボタンをクリックすると次のような結果が表示されるでしょう。

表示されたメニュー画面の上段にログイン時に指定したIDとログイン日時が表示されているのがわかります。ログイン処理( login.php )へのリクエストと、リダイレクト後のメニュー画面表示処理( menu.php )へのリクエストは異なるリクエストです。このような一連のやりとりの中でデータを共有するためにはセッション( $_SESSION )を使う必要があります。

まとめ

  • ユーザごとの一連のやりとりを記録する仕組みをセッションと呼ぶ
  • セッション利用するにはを session_start 関数を呼び出す
  • セッション( $_SESSION 変数)に保存したデータは、以降のリクエストにおいて再利用できる