PHPのセッション管理はプログラムをする上で必須機能だが、あまり細かく考えたことが無かった。
まず、セッションの引継ぎ方法は、ユーザのブラウザでCookieが使えると仮定すれば、サーバ側で何も考えなくても引継ぎが行えている。 しかし、セキュリティ上の理由でCookieが保存されないように設定されている端末では、プログラムが利用できない不具合が出る。
セッションの引き渡し方をメモしてみると
Cookieが使える時 : ボタンコントロールのPOSTでページ遷移
<html>
<body>
<?php
session_start();
print "session_id = " . session_id() . "<br>";
print "session_name = " . session_name() . "<br>";
print "session_save_path = " . session_save_path() . "<br>";
$_SESSION['ticket'] = md5(uniqid().mt_rand()); // 引き渡したい情報
print('ticket = ' . $_SESSION['ticket'] . '<br>');
?>
<form action="test1_receive.php" method="post">
<input type="hidden" name="ticket" value="<?= htmlspecialchars($_SESSION['ticket'], ENT_QUOTES); ?>">
<input type="submit" name="submit_button" value="次のページへ移動">
</form>
</body>
</html>
Cookieが使えない時 : ボタンコントロールのPOSTでページ遷移
<html>
<body>
<?php
session_start();
print "session_id = " . session_id() . "<br>";
print "session_name = " . session_name() . "<br>";
print "session_save_path = " . session_save_path() . "<br>";
$_SESSION['ticket'] = md5(uniqid().mt_rand()); // 引き渡したい情報
print('ticket = ' . $_SESSION['ticket'] . '<br>');
?>
<form action="test1_receive.php" method="post">
<input type="hidden" name="ticket" value="<?= htmlspecialchars($_SESSION['ticket'], ENT_QUOTES); ?>">
<input type="hidden" name="<?=session_name()?>" value="<?=session_id()?>">
<input type="submit" name="submit_button" value="次のページへ移動">
</form>
</body>
</html>
Cookieが使えない時 : リンク a href= でページ遷移
<html>
<body>
<?php
session_start();
print "session_id = " . session_id() . "<br>";
print "session_name = " . session_name() . "<br>";
print "session_save_path = " . session_save_path() . "<br>";
$_SESSION['ticket'] = md5(uniqid().mt_rand()); // 引き渡したい情報
print('ticket = ' . $_SESSION['ticket'] . '<br>');
?>
<a href="test1_receive.php?<?=SID?>">次のページへ移動</a>
</body>
</html>
なお、Cookieが使えるかどうかは、サーバ側でCookieにセッション情報を格納するオプションがONになっていない限り、ブラウザで幾らがんばっても使えない。
/etc/php.ini
; Whether to use cookies.
session.use_cookies = 1
情報を受け取る側のプログラムはこんな感じになる。 プログラムでは特別なコーディング無しに、セッション情報が引き継がれてくる。
情報を受け取る側のプログラム (test1_receive.php)
<html>
<body>
<?php
session_start();
print "session_id = " . session_id() . "<br>";
print "session_name = " . session_name() . "<br>";
print "session_save_path = " . session_save_path() . "<br>";
print('ticket = ' . $_SESSION['ticket'] . '<br>');
$_SESSION = array(); // セッション変数を全てクリア
session_destroy(); // セッションファイルを削除
?>
</body>
</html>
セッション情報を利用し終われば、サーバ側で利用しているセッション情報ファイルは消去すべきである。そのためのコマンドが、session_destroy(); だが、ユーザがページ途中で閲覧を放棄してしまった場合、セッションファイルが削除されずに残ることになる。
サーバにひたすら溜まり続けていくのかと思っていたが、ガベージコレクションでちゃんと消去してくれているようである。
CentOS 5 で、PHPのセッション一時ファイルの保管場所は、/var/lib/php/session なので、ネット上の一般的な情報の /tmp で無いからcronのスケジューラの自動削除対象にはあたっていないのだが、次の設定で自動消去されている。
/etc/php.ini
; Define the probability that the 'garbage collection' process is started
; on every session initialization.
; The probability is calculated by using gc_probability/gc_divisor,
; e.g. 1/100 means there is a 1% chance that the GC process starts
; on each request.
session.gc_probability = 1
session.gc_divisor = 1000
; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
session.gc_maxlifetime = 1440
1000回アクセスがあるごとに、ガベージコレクションが1440秒(24分)以上経過したセッションファイルを自動削除してくれる。