PHPの基礎 - セッション
概要
Webセッションは、Webアプリケーション開発において、重要な概念の1つである。
セッションは、ユーザがWebサイトやアプリケーションとの対話中に維持される状態情報を管理する仕組みである。
これにより、ユーザがWebページ間を移動する際に、一時的なデータや認証情報を保持することができる。
セッションは、ユーザの操作の一貫性を維持するものである。
Webセッションの役割として、ユーザがWebサイト上で何か特定の操作を行う間、その操作のコンテキストや状態を保持するのに役立つ。
例えば、ショッピングサイトのカートに商品を追加する場合、セッションはそのカート内の商品リストや数量を保持することができる。
このように、セッションは、ユーザエクスペリエンスを向上させるのに役立つ重要なものである。
セッションの開始
セッションとは、クッキーは管理する値をクライアントに保存するのに対して、セッションは管理する値をサーバに保存する。
クライアントには、どのセッションを使用しているかを識別するためのセッションIDのみをクライアントに保存する。
一般的に、セッションIDをクッキーの値としてクライアントに保存する。(セッションを使用する場合、クッキーも同時に使用する)
また、重要なデータを扱う場合はセッションを使用する。
クライアントから初めてアクセスがある場合、session_start
関数を使用して、新しいセッションを作成してセッションを開始する必要がある。
bool session_start() session_start関数は、セッションを作成する。 もしくは、リクエスト上でGET、POST、クッキーにより渡されたセッションIDに基づき、 現在のセッションを復帰する。 戻り値: 常にTRUEを返す。
セッションが開始されていない状態でsession_start
関数が呼ばれる場合、新しいセッションを開始してセッションIDを割り当てる。
セッションIDは、クライアントにクッキー名PHPSESSID
で保存される。
(クライアントがクッキーを利用できない場合、次のセクションに記載する)
既にセッションが開始されているクライアント(既にセッションIDがクッキーとして保存されているクライアント)からアクセスがある場合、
session_start
関数を実行しても新たにセッションを開始せずに、サーバに保存されているセッション変数を利用できるように準備する。
以下の例では、セッションを開始して、クライアントにセッションIDがクッキーとして保存しているか確認している。
初めてアクセスする場合、セッションIDが割り当てられて、クライアントは自動的にクッキーを利用してセッションIDを保存する。
次回以降は、クッキー名PHPSESSIDがクライアントから送信されて、新たにセッションは開始されずに、以前のものを利用する。
また、セッションIDにはランダムな値が設定される。
<?php
session_start();
?>
<?php
if(!isset($_COOKIE["PHPSESSID"]))
{
print('初回の訪問です。セッションを開始します。');
}
else
{
print('セッションは開始しています。<br>');
print('セッションIDは '.$_COOKIE["PHPSESSID"].' です。');
}
?>
セッション変数の書き込みと読み込み
セッションを開始することで、サーバに管理する値(セッション変数と呼ぶ)を複数保存することができる。
クライアントごとに様々な値が書き込まれるため、セッションIDを識別子として、クライアントを識別することができる。
セッション変数に値を書き込む場合は、定義済みの変数$_SESSION
を使用する。
$_SESSION[セッション変数名] = 値
例えば、セッション変数visitedに値を書き込む場合、以下のように記述する。
$_SESSION["visited"] = 1;
以下の例では、セッションを開始して、セッション変数visitedに値を保存している。
同一のWebページにアクセスするごとにセッション変数の値を増加させて、前回アクセスした日時も表示している。
<?php
session_start();
?>
<?php
if(!isset($_SESSION["visited"]))
{
print('初回の訪問です。セッションを開始します。');
$_SESSION["visited"] = 1;
$_SESSION["date"] = date('c');
}
else
{
$visited = $_SESSION["visited"];
$visited++;
print('訪問回数は'.$visited.'です。<br>');
$_SESSION["visited"] = $visited;
if(isset($_SESSION["date"]))
{
print('前回の訪問日時は'.$_SESSION["date"].'です。<br>');
}
$_SESSION["date"] = date('c');
}
?>
セッション変数の削除とセッションIDの削除
保存されたセッション変数を削除するには、unset
関数を使用する。
void unset(mixed var [, mixed var [, mixed ...]]) unset関数は、指定した変数を破棄する。 パラメータ: var 削除したい変数
以下の例では、セッション変数visitedを削除している。
unset($_SESSION("visited"));
また、全てのセッション変数を削除するには、以下のように空の配列を変数$_SESSION
に代入する。
$_SESSION = array();
※注意
変数$_SESSION
自体を削除しないこと。
ログアウト等でセッション自体を破棄する場合、クライアントに保存されているセッションIDを削除した後、セッションを破棄する。
まず、クライアントにはクッキーが保存されているため、クッキーを削除する。
(クッキーの削除については、PHPの基礎 - クッキー#クッキーの削除を参照すること)
if(isset($_COOKIE["PHPSESSID"]))
{
setcookie("PHPSESSID", '', time() - 1800, '/');
}
次に、session_destroy
関数を使用して、セッションに登録された値を全て破棄する。
bool session_destroy(void) session_destroy関数は、現在のセッションに 関連づけられた全てのデータを破棄する。 この関数は、セッションに関するグローバル変数を破棄しない。 また、セッションクッキーを破棄しない。 戻り値: 成功した場合はtrue、失敗した場合はfalseを返す。
以下の例では、Sample1.phpのログアウトのリンクを選択して、Sample2.phpでセッションとクッキーを削除している。
次に、Sample3.phpでセッションとクッキーが正常に削除されているかを確認している。
// Sample1.php
<?php
session_start();
?>
<?php
if(!isset($_SESSION["visited"]))
{
print('初回の訪問です。セッションを開始します。');
$_SESSION["visited"] = 1;
$_SESSION["date"] = date('c');
}
else
{
$visited = $_SESSION["visited"];
$visited++;
print('訪問回数は'.$_SESSION["visited"].'です。<br>');
$_SESSION["visited"] = $visited;
if(isset($_SESSION["date"]))
{
print('前回の訪問日時は'.$_SESSION["date"].'です。<br>');
}
$_SESSION["date"] = date('c');
}
?>
<p><a href="./Sample2.php">ログアウトする</a></p>
// Sample2.php
<?php
session_start();
?>
<?php
print('セッション変数の一覧を表示します。<br>');
print_r($_SESSION);
print('<br>');
print('セッションIDを表示します。<br>');
print($_COOKIE["PHPSESSID"].'<br>');
print('<p>ログアウトします</p>');
$_SESSION = array();
if(isset($_COOKIE["PHPSESSID"]))
{
setcookie("PHPSESSID", '', time() - 1800, '/');
}
session_destroy();
print('<p>ログアウトしました</p>');
?>
<p><a href="./Sample3.php">ログアウトの確認</a></p>
// Sample3.php
<?php
session_start();
?>
<?php
print('セッション変数の確認をします。<br>');
if(!isset($_SESSION["visited"]))
{
print('セッション変数visitedは登録されていません。<br>');
}
else
{
print($_SESSION["visited"].'<br>');
}
print('セッションIDの確認をします。<br>');
if(!isset($_COOKIE["PHPSESSID"]))
{
print('セッションは登録されていません。<br>');
}
else
{
print($_COOKIE["PHPSESSID"].'<br>');
}
?>
セッション名の取得と変更
セッションを開始した時、クライアントのクッキー名として使用する変数(セッション名)において、初期値はPHPSESSIDである。
この値の初期値は、php.iniファイルで設定されている。
この初期値を変更する場合は、php.iniファイルのsession.name
項目を編集する。
セッション名は英数字を組み合わせて指定する必要がある。
例. session.name = HOGE
セッション名がPHPSESSIDではない可能性があるため、session_name
関数を使用してセッション名を取得する。
string session_name([string name]) session_name関数は、カレントのセッション名を返す。 nameを指定する場合、カレントのセッション名はその値に変更される。 セッション名は、リクエストが開始された際に セッション名に保存されたsession.nameの値にリセットされる。 したがって、各リクエストごとに(session_start関数またはsession_register関数を呼ぶ前に)、session_name関数を実行する必要がある。 パラメータ: name 新しく設定したいセッション名 戻り値: 現在のセッション名
session_name
関数を引数無しで実行することにより、現在のセッション名を取得できる。
また、引数に別のセッション名を指定する場合は、セッション名を変更することが可能である。
<?php
session_name("phpsession");
session_start();
?>
<?php
print('現在のセッション名は'.session_name().'です。');
?>
セッションIDの取得と変更
セッションIDは自動的にランダムな値が設定されるが、session_id
関数を使用して、任意の値に設定することもできる。
string session_id([string id]) session_id関数は、カレントのセッションIDを取得・設定するために使用される。 パラメータ: id カレントのセッションIDを置換する。その際、session_start関数の前に呼ぶ必要がある。 セッションハンドラによっては、セッションIDとして使用できる文字に制限がある場合がある。 例えば、ファイルによるセッションハンドラにおいて、セッションIDとして使用できる文字は、a-z、A-Z、0-9に限られる。 戻り値: session_id関数は、カレントのセッションのセッションID・カレントセッションが存在しない(カレントのセッションIDが存在しない)場合、 空文字列""を返す。
session_id
関数を引数無しで使うことで現在のセッションIDを取得することができる。
また、引数に値を指定する場合は、セッションIDを指定した値に変更できる。
ただし、セッションIDは、セッションハイジャック等を防ぐためにも簡単な値を設定してはならない。
したがって、任意でセッションIDを指定しない方がよいと考えられる。
<?php
session_start();
?>
<?php
if(!isset($_COOKIE[session_name()]))
{
print('初回の訪問です。セッションを開始します。');
}
else
{
print('セッションは開始しています。<br>');
print('クッキーは '.$_COOKIE[session_name()].' です。<br>');
print('session_id関数は '.session_id().' です。<br>');
}
?>
セッションIDの自動変更
セッションIDが漏洩すると、セッションを乗っ取られる可能性がある。
そのため、セッションIDを常に変更することにより、セキュリティを向上させることができる。
session_regenerate_id
関数を使用して、現在のセッションを終了させることなくセッションIDのみを新しい値に変更できる。
bool session_regenerate_id ( [bool delete_old_session] ) session_regenerate_id関数は、現在のセッションIDを新しい値に変更する。 その際、現在のセッション情報は維持される。 パラメータ: (PHP 5.1以降) delete_old_session 関連付けられた古いセッションを削除するかを決める。 初期値はfalseである。 古いセッション情報を残すことは資源の無駄かつセキュリティも悪くなるため、trueを指定することを推奨する。 戻り値: 成功した場合はtrue、失敗した場合はfalseを返す。
以下の例では、Webページを読み込むたびに、セッションIDを変更している。
<?php
session_start();
$old_id = session_id();
session_regenerate_id(true);
$new_id = session_id();
?>
<?php
if(!isset($_COOKIE[session_name()]))
{
print('初回の訪問です。セッションを開始します。');
}
else
{
print('前のセッションIDは '.$old_id.' です。<br>');
print('今のセッションIDは '.$new_id.' です。<br>');
}
?>