PHPセッションをDBで管理 - PHPセッション管理のコールバック関数を設定編
前回エントリ PHPセッションをDBで管理 - OracleでのAutoIncrement用テーブルを作成編 の続きです。
前回はOracleでセッション管理用のテーブルを作成するところまで行ないました。
今回は、そのテーブルを使って実際にPHPからセッション管理を行うのをやってみます。
※参考にさせてもらったページ
PHPのセッションをDB管理するにあたり、全体的な部分は「Web Artisan Blog」、OracleでAutoIncrementについては「イイ!! プログラミング Blog」、OracleのCLOBの更新方法等については「あるプログラマーのつぶやき」を参考にさせていただきました。
PHPセッション管理のコールバック関数の作成〜設定
PHPのセッションはデフォルトでファイルを使用するようになっているため、まずは設定を変更します。これはphp.iniまたはini_setで「session.save_handler」を「user」に設定すればOKです。
次に実際にセッション管理用の関数を定義します。
定義する関数としては、以下のようなものになります。
(表の関数名は当エントリのサンプルコードの関数名です。実際には任意の名前を付けられます。)
関数名 | 用途 |
---|---|
sess_open | セッションのオープン時に実行される関数,コンストラクタのようなもの |
sess_close | セッションのクローズ時に実行される関数,デストラクタのようなもの |
sess_read | セッションの読み込み時に実行される関数,セッションIDをキーにしてセッション情報を取得する処理を書く |
sess_write | セッションの書き込み時に実行される関数,セッションIDをキーにしてセッション情報を更新する処理を書く |
sess_destroy | セッション破棄時に実行される関数,セッションIDをキーにしてセッション情報を削除する処理を書く |
sess_clean | ガベージコレクション実行時に実行される関数,maxlifetime以上経過しているセッションを削除する処理を書く |
定義した関数については「session_set_save_handler」で、セッション管理用コールバック関数として設定をします。
設定の例
<?php session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_clean'); ?>
ここまで出来たら、あとは普通に「session_start();」でセッション開始したり、「$foo = $_SESSION['foo'];」「$_SESSION['bar'] = $bar;」とかでセッションの読み書きが出来るようになります。
もちろんセッション情報はDBに書き込まれます。
下記に、今回作成したサンプルコードを書いておきます。
今回作成したサンプルコード
※エラー制御とかをぶっちぎっているのはご了承ください。
<?php ini_set('session.save_handler', 'user'); //セッションのオープン時 function sess_open() { return true; } //セッションのクローズ時 function sess_close() { return true; } //セッションの読み込み時 function sess_read($id) { // セッションの取得(テーブル:sessions) // sessions.dataはCLOB型 $conn = oci_connect("username", "password", "oracle_sid"); $sql = "SELECT data FROM sessions WHERE sess_id = '$id'"; $stmt = oci_parse($conn, $sql); oci_execute($stmt, OCI_DEFAULT); while ( $row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_LOBS) ){ $data = $row['DATA']; } oci_free_statement($stmt); oci_close($conn); return $data; } //セッションの書き込み時 function sess_write($id, $data) { // セッションを一度削除 $conn = oci_connect("username", "password", "oracle_sid"); $sql = "DELETE FROM sessions WHERE sess_id = '" . $id . "'"; $stmt = oci_parse($conn, $sql); oci_execute($stmt, OCI_DEFAULT); // 新たなシーケンスでセッションを再度書き込み // シーケンスはOracleトリガーで自動インクリメントされる $sql = "INSERT INTO sessions (sess_id, data, update_time) VALUES ('$id', empty_clob(), sysdate) RETURNING data INTO :lob"; $stmt = oci_parse($conn, $sql); $clob = oci_new_descriptor($conn, OCI_D_LOB); oci_bind_by_name($stmt, ":lob", &$clob, -1, OCI_B_CLOB); oci_execute($stmt, OCI_DEFAULT); $clob->save($data); oci_commit($conn); oci_free_statement($stmt); oci_close($conn); $rtn = true; return $rtn; } //セッション破棄時(session_destroy時) function sess_destroy($id) { // セッションの削除 $conn = oci_connect("username", "password", "oracle_sid"); $sql = "DELETE FROM sessions WHERE sess_id = '" . $id . "'"; $stmt = oci_parse($conn, $sql); oci_execute($stmt, OCI_DEFAULT); oci_commit($conn); oci_free_statement($stmt); oci_close($conn); $rtn = true; return $rtn; } //ガーベージコレクション実行時 function sess_clean($maxlifetime) { // 最終更新日時からmaxlifetime以上経過しているセッションを削除 $conn = oci_connect("username", "password", "oracle_sid"); $sql = "DELETE FROM sessions WHERE update_time < ( sysdate - " . $maxlifetime . " / 86400 )"; $stmt = oci_parse($conn, $sql); oci_execute($stmt, OCI_DEFAULT); oci_commit($conn); oci_free_statement($stmt); oci_close($conn); $rtn = true; return $rtn; } // セッション管理用のユーザー定義のコールバック関数を設定する。 session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_clean'); ?>