2012年3月11日日曜日

PHPのsessionをDBに保存する。その壱

実装したいこと。
  • phpのsessionをDBに保存する。
  • sessionに期限を持たせて使いたい。cookieと同様の使い方。
  • DBに保存されたdataを定期的に削除したい。
  • phpのバージョンは5.3以下
document rootが/var/www/html
その下にsessiontestを作成。その中に以下のファイルを作成。
DBSession.php  db_test.php  db_test2.php  log.txt
tableの作成
CREATE TABLE `sessions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `session_id` char(32) NOT NULL,
  `data` text,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_session_id` (`session_id`),
  KEY `idx_created_at` (`created_at`),
  KEY `idx_updated_at` (`updated_at`)
) 
DBSession.php
session.save_handler
sessionの保存先をユーザー定義に変更。
session_set_save_handlerでユーザー定義関数を指定。
名前は何でもいいですけど、わかりやすい名前がいいです。
session.gc_maxlifetime
第6引数、下記の例だとgc関数に渡される引数の時間を指定します。
ここでは100秒を指定。
gcが動く確率は gc_probability/gc_divisorで設定されます。
今回は100%動かしたいので100/100*100=100%に設定しました。
session_set_cookie_paramsには100秒を指定しました。
これでブラウザを落としても、sessionが有効になっています。
少し微妙な言い回しですけど。

<?php

    ini_set('session.save_handler', 'user');

    ini_set('session.gc_maxlifetime', 100);

    ini_set('session.gc_probability', 100);

    ini_set('session.gc_divisor', 100);



    session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');

    session_set_cookie_params(100);



    define('HOST', "localhost");

    define('USER', "root");

    define('PASSWORD', "");

    define('DATABASE', "development");

    if(isset($_COOKIE["PHPSESSID"])){

        session_id($_COOKIE["PHPSESSID"]);

    }



    function open(){

        return true;

    }



    function close(){

        return true;

    }



    function read($session_id){

        $rtn = "";

        $db = new mysqli(HOST, USER, PASSWORD, DATABASE);



        $session_id = mysql_real_escape_string($session_id);



        $select_data  = "SELECT data "

                      . "FROM sessions "

                      . "WHERE session_id = '" . $session_id . "'";

        $fp = fopen("log.txt", "a+");

        fwrite($fp, "read: " . $select_data . "\n");



        $rs = $db->query($select_data);

        if($rs){

            while ($row = $rs->fetch_assoc()) {

                $rtn = $row['data'];

            }

        }


   function write($session_id, $data){

        $rtn = false;

        $db = new mysqli(HOST, USER, PASSWORD, DATABASE);

        $session_id = mysql_real_escape_string($session_id);

        $data = mysql_real_escape_string($data);



        $select_sessions = "SELECT * FROM sessions WHERE session_id='" . $session_id . "'";

        $fp = fopen("/var/www/html/sessiontest/log.txt", "a+");

        fwrite($fp, "write: " . $select_sessions . "\n");

        $rs = $db->query($select_sessions);

        if($rs->fetch_row() > 0){

            $update_sessions  = "UPDATE sessions "

                               . "SET data = '" . $data . "',"

                               . "updated_at =  NOW() "

                               . "WHERE session_id = '" . $session_id . "'";

            $rs = $db->query($update_sessions);

        }else{

            $insert_sessions  = "INSERT INTO sessions(session_id, data, created_at)"

                                 . "VALUES('" . $session_id . "','" . $data . "',NOW())";

            $rs = $db->query($insert_sessions);

            var_dump($rs);

        }



        $rtn = true;



        return $rtn;

    }




        return $rtn;

      }


 function destroy($session_id){

        $db = new mysqli(HOST, USER, PASSWORD, DATABASE);

        $delete_sessions = "DELETE FROM sessions WHERE session_id = '" . $session_id . "'";

        $fp = fopen("/var/www/html/sessiontest/log.txt", "a+");

        fwrite($fp, "destroy: " . $delete_sessions . "\n");

        $db->query($delete_sessions);



        return true;

    }



    function gc($maxlifetime){

        $rtn = false;

        $db = new mysqli(HOST, USER, PASSWORD, DATABASE);



        $gc_sessions  = "DELETE "

                           . "FROM sessions "

                           . "WHERE updated_at < current_timestamp + '-" . $maxlifetime . " secs' "

                           . " OR (created_at < current_timestamp + '-" . $maxlifetime . " secs' AND updated_at IS NULL)";



        $db->query($gc_sessions);

        $fp = fopen("/var/www/html/sessiontest/log.txt", "a+");

        fwrite($fp, "gc: " . $gc_sessions . "\n");



        $rtn = true;



        return $rtn;



    }

db_test.php
<?php
require_once 'DBSession.php';
session_start();
$_SESSION["box"] = "test";
var_dump($_SESSION);

db_test2.php
<?php
  require_once 'DBSession.php';
  session_start();
  var_dump($_SESSION);
  session_destroy();

0 件のコメント: