PHPのSession(セッション)について、「そもそもSessionとは?」と「Sessionを使う方法」を書いています。
実際にセッションを使用したサンプルコードを載せています。PHPのバージョンは7で試しています。
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を発行してブラウザのクッキーに保持します。
データはサーバーのファイルとして、保持しています。
ユーザーからアクセスがあって、セッションからデータを取得する場合です。
クッキーに持っているセッションIDを使用して、サーバーのセッションファイルの情報を取得します。
ユーザーのセッション毎に個別のレスポンスを返すことができます。
なので、ブラウザのクッキーを削除するとセッションも切れます。
ブラウザのクッキーはブラウザから手動で削除することが可能です。
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.php
にheader
関数を使用してリダイレクトしています。
実際のログイン処理を書く場合ですが、
セッションにユーザー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
にアクセスすると、下記のようにフォームが表示されます。
ユーザーIDとパスワードを入力して、送信します。
今回はパスワードは何にも使ってないので、入力しなくても試すことは可能です。😄
入力内容がユーザーIDというよりユーザー名のようになってしまいましたが、特にバリデーションなどもしていないので、これでも問題ないです(笑)
ログインすると、下記のように入力した内容が表示されました。
入力したユーザーIDがセッション($_SESSION["userId"]
)として保持されます。
ログアウトリンクをクリックすると、logout.php
が動いてセッションを破棄します。
マイページリンクをクリックすると、下記のようにセッションにユーザーIDが保持されて、画面表示されたことが確認できます。
カウンターがあるので、クリックしてみると、このようにPOST処理が走ります。
そして、セッションに$_SESSION["count"]
という名前でデータが保持されて、カウントアップされていることが確認できました。
コメント