PHPでSession(セッション)を使う方法や仕組みを解説!

PHP

PHPのSession(セッション)について、「そもそもSessionとは?」と「Sessionを使う方法」を書いています。
実際にセッションを使用したサンプルコードを載せています。PHPのバージョンは7で試しています。

PHPのセッションについての公式のドキュメントは下記になります。
PHP: Sessions - Manual

Session(セッション)とは?

セッションはサイトのユーザー毎に、個別の情報を保持しておけるものです。
セッションを使うことで、Webページを遷移しても、個別のユーザーに対する情報を保持しておくことが可能です。
クライアントのブラウザではなく、サーバーにファイルが作成されて保持されます。

ふわっとしているので、具体的にECサイトの例で考えてみましょう。
codelikes.comはログインが必要なショッピング(EC)サイトと仮定します)

ブラウザを開いて、`https://codelikes.com`にHogeさんがアクセスします。
サイト自体にサクセスされたときには、誰がアクセスしてきたか判断できません。

Hogeさんがメールアドレスとパスワードを入れてログインします。
そうすると、サーバー上でデータベースに登録された情報を元にHogeさんが来たことがわかります。

そのときにログイン状態を保つために、セッションを使用します。
セッションにはユーザー名やユーザーIDを持っておくことが多いです。

サーバー側では、セッションに入っているユーザーIDなどから、ユーザーを判断します。
そして、個別のマイページやおすすめ商品情報などをユーザーに表示するといった形です。

PHPでSession(セッション)を使う方法

PHPのセッションはPHPが使えるようになると、特に設定が不要で初めから使うことが可能です。

セッションを使う時にはsession_start関数を読み出して、セッションを開始する必要があります。
それぞれのページで読み込み時に使用して、セッションを開始します。

session_start関数でセッションを使えるようになると、$_SESSION変数にアクセスできるようになります。
$_SESSIONはPHPでセッションを使うための特別な変数です。

例えば、”userId”という名前で番号を保持したい場合は下記のようになります。

<?php
session_start();

$_SESSION["userId"] = 1;

セッションを開始した後に、$_SESSION変数の連想配列に対して値を格納しておきます。
これを取り出したい場合は、下記のように連想配列を使うときのように取り出すだけです。

<?php
session_start();

echo $_SESSION["userId"]; // 1が表示される

この$_SESSIONを使用した連想配列には、文字列や配列、クラスのインスタンスなど柔軟に値を設定することができます。
初期の状態でセッションが保たれるのは、ブラウザが閉じられるまで、またはセッションがタイムアウトするまでです。

公式の下記のページにもセッションの基本的な使い方が書いていますので、参考にしてみてください。
PHPのセッション:基本的な使用法

Session(セッション)の仕組みについて

前述した方法でセッションを使うことができます。
ここでは、PHPのセッションの仕組みについて考えてみます。

セッションのデータは、サーバー上のファイルとして管理されます。
どのデータが、どのユーザーと関連するかはブラウザに発行されたクッキーのセッションIDを使用して判断しています。

セッションを作成して、情報を取得する場合を考えます…

初回アクセスでユーザーがブラウザからsession_startが呼ばれているファイルにアクセスすると、サーバーではセッションIDを発行してブラウザのクッキーに保持します。
データはサーバーのファイルとして、保持しています。

PHPのセッション解説・セッション開始

ユーザーからアクセスがあって、セッションからデータを取得する場合です。
クッキーに持っているセッションIDを使用して、サーバーのセッションファイルの情報を取得します。
ユーザーのセッション毎に個別のレスポンスを返すことができます。

PHPのセッション解説・セッションで個別レスポンス

なので、ブラウザのクッキーを削除するとセッションも切れます。
ブラウザのクッキーはブラウザから手動で削除することが可能です。

Session(セッション)のタイムアウトを伸ばしたい

PHPの設定として、session.gc_maxlifetimeが存在します。
これがPHPのセッションを保つ長さです。時間が切れるとセッションファイルが削除されます。
指定するのは秒単位になります。

php.iniファイルに設定するか、ini_setなどの関数を使用して一時的に変えると良いかと思います。
1440秒だと、24分ですね。

session.gc_maxlifetime = 1440

Session(セッション)の保存先は?

Sessionファイルが保存される先は、php.iniなどでPHPに設定されたsession.save_pathの場所になります。
この値が空の場合は、デフォルトの/tmp配下にセッションファイルが作成されます。

session.save_pathはphpinfo関数で確認するか、下記コマンドでも確認可能です。

# php -i | grep session.save_path
session.save_path => no value => no value

no valueの場合は/tmp配下が使用されます。

Session(セッション)を使ったサンプルコード

PHPのセッションを使用した簡単なサンプルコードを書いてみました。
ログイン画面からログインして、他のページにセッションが引き継がれるか確認するサンプルです。

ログイン処理についてはデータベースが必要なので、今回はやっていません。
「ユーザーのIDが入っていたらログインできた」ということにして、セッションの挙動を確認します。

サンプルコードのそれぞれのファイルは、同じ階層に入れて使用しています。

ログインするページの作成

ログインページをlogin.htmlという名前で作成しました。

<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>session test page</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  </head>
  <body>
    <div class="container">
      <div class="d-flex justify-content-center mt-5">
        <form action="login.php" method="post" class="row">
          <input type="text" name="user_id" class="form-control mb-2" placeholder="ユーザーID" />
          <input type="password" name="password" class="form-control mb-2" placeholder="パスワード" />
          <button class="btn btn-primary">送信</button>
        </form>
      </div>
    </div>
  </body>
</html>

ユーザーIDとパスワードを入れてログインするイメージです。
送信ボタンを押すとpost形式で、login.phpに入力された内容を送信します。

ログイン処理をするページ

login.phpという名前で、先ほどのファイルからPOSTを受けて、ログインのような処理を作成しました。
ログインと言っても、今回はセッションの確認のためなので、入力されたユーザーIDをそのまま保持するような形です。

<?php
    session_start();

    $userId = isset($_POST['user_id']) ? $_POST['user_id'] : '';
    if (empty($userId)) {
      echo 'ユーザーIDを入力してください。<br />';
      echo '<a href="login.html">戻る</a>';
      exit;
    }

    $_SESSION['userId'] = $userId;

    header('Location: home.php');

最初にsession_startでセッションを開始しています。これがない場合は$_SESSION変数が使用できません。
入力されたユーザーIDを取得して、$userIdに格納します。

ユーザーIDがなかった場合は、ログインフォームに戻るリンクを表示して処理を終了します。
ユーザーIDがあった場合は、セッションの$_SESSION['userId']にユーザーIDを設定しました。

ログインできたら、home.phpheader関数を使用してリダイレクトしています。

実際のログイン処理を書く場合ですが、
セッションにユーザーIDを格納する前にパスワードとユーザIDがあっているか、データベースと合わせて確認して、あっていたらセッションに格納して処理を継続といった形になるかと思います。

ユーザーのホーム画面

home.phpという名前で、ユーザーのホーム画面を下記のように作成しました。

<?php
    session_start();
?>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>session test home</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  </head>
  <body>
    <div class="container">
      <div class="mt-5">
        <?php echo $_SESSION["userId"] ?>さん、こんにちは。
      </div>
      <a href="mypage.php">マイページへ</a>
      <a href="logout.php">ログアウトする</a>
    </div>
  </body>
</html>

セッションに入っているユーザーIDを元に、挨拶文を表示しています。
最初のログイン画面で入力した値が、セッションに格納されているので、その内容が表示される想定です。

ユーザーのマイページ画面

mypage.phpという名前で、ユーザーのマイページ画面を下記のように作成しました。

<?php
    session_start();

    if (isset($_POST['postFlag'])) {
        if (isset($_SESSION["count"])) {
            $_SESSION["count"] = $_SESSION["count"] + 1;
        } else {
            $_SESSION["count"] = 0;
        }
    }
?>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>session test mypage</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  </head>
  <body>
    <div class="container">
      <div class="mt-5">
        <?php echo $_SESSION["userId"] ?>のマイページです。
      </div>
      <form action="mypage.php" method="post" class="mt-2">
        <input type="hidden" name="postFlag" value="1" />
        <div>カウント回数:<?php echo isset($_SESSION["count"]) ? $_SESSION["count"] : '' ?></div>
        <button class="btn btn-success">テストカウント</button>
      </form>
      <a href="./home.php">ホームへ戻る</a>
    </div>
  </body>
</html>

ホームと同じように入力されたユーザーIDを表示しています。
あとは、セッションを使用したカウンターを設置してみました。

「テストカウント」ボタンが押されると、セッションを使用してカウントが1ずつ上がっていきます。
自分のファイル(mypage.php)に対して、POST形式でリクエストを飛ばしてカウントアップします。

ファイルの先頭にある下記の処理はカウントアップのための処理です。

if (isset($_POST['postFlag'])) {
    if (isset($_SESSION["count"])) {
        $_SESSION["count"] = $_SESSION["count"] + 1;
    } else {
        $_SESSION["count"] = 0;
    }
}

そのままだと、画面のリロードや読み込み時にもカウントアップされてしまうため、postFlagを参照するようにしました。
フォームにhiddenで設定している項目です。

セッションに”count”が格納されていれば、カウントアップされます。
格納されていない場合は0で初期化するようにしています。

ユーザーのログアウト処理

logout.phpという名前で、ログアウト処理を作成しました。
このファイルはホーム画面からログアウトリンクが押されると、実行される処理です。

<?php
session_start();
$_SESSION = [];
session_destroy();

header('Location: ./login.html');
exit;

処理の内容としては、session_destroy関数を使ってセッションを破棄しています。
session_destroy関数だけだと、$_SESSION変数の内容は空にならないので、空の配列を設定しています。

セッションの破棄が終わると、ログイン画面に戻しています。

動作確認

login.htmlにアクセスすると、下記のようにフォームが表示されます。
PHPのセッション確認・ログイン画面

ユーザーIDとパスワードを入力して、送信します。
今回はパスワードは何にも使ってないので、入力しなくても試すことは可能です。😄
PHPのセッション確認・ログイン処理
入力内容がユーザーIDというよりユーザー名のようになってしまいましたが、特にバリデーションなどもしていないので、これでも問題ないです(笑)

ログインすると、下記のように入力した内容が表示されました。
PHPのセッション確認・ホーム画面
入力したユーザーIDがセッション($_SESSION["userId"])として保持されます。
ログアウトリンクをクリックすると、logout.phpが動いてセッションを破棄します。

マイページリンクをクリックすると、下記のようにセッションにユーザーIDが保持されて、画面表示されたことが確認できます。
PHPのセッション確認・マイページ画面

カウンターがあるので、クリックしてみると、このようにPOST処理が走ります。
そして、セッションに$_SESSION["count"]という名前でデータが保持されて、カウントアップされていることが確認できました。
PHPのセッション確認・セッションカウンターのテスト

コメント

タイトルとURLをコピーしました