2012年3月19日月曜日

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

php5.4から実装されたSessionHandlerInterfaceを使って
sessionをDBに保存しました。
適当にさわったり、ブラウザを落としてみて動作を確認してみて下さい。
Session.php
<?php 
ini_set('session.gc_maxlifetime', 100);
ini_set('session.gc_probability', 100);
ini_set('session.gc_divisor', 100);
session_set_cookie_params(100);

class Session implements SessionHandlerInterface
{
 private $_db;
 private $_fp;

 public function __construct(){
  try{
   $this->_fp = fopen("log.txt", "a+");
   fwrite($this->_fp, "construct: "."\n");
   $this->_db = mysql_connect('localhost', 'root', '');
   $db_selected = mysql_select_db('development');
   if(!$db_selected){
    throw new Exception("SQLException DBの接続に失敗しました"); 
   }
   if(isset($_COOKIE["PHPSESSID"])){
    session_id($_COOKIE["PHPSESSID"]);
   }
  }catch(Exception $e){
   fwrite($this->_fp, $e->getMessage()."\n");
   throw $e;
  }
 }
 public function open($save_path, $session_id)
 {
  fwrite($this->_fp, "open: "."\n");
     return true;
 }
  
 public function read($session_id)
 {
  try{
   $session_id = mysql_real_escape_string($session_id);
   $select_data = "SELECT data "
       . "FROM sessions "
       . "WHERE session_id = '" . $session_id . "'";
   fwrite($this->_fp, "read: " . $select_data . "\n");
   $result = mysql_query($select_data);
   if(!$result){
    throw new Exception("SQLException dataの取得に失敗しました");
   }
   $row = mysql_fetch_row($result);

   return $row[0];

  }catch(Exception $e){
   fwrite($this->_fp, $e->getMessage()."\n");
   throw $e;
  }
 }

 public function write($session_id, $session_data)
 {
  try{
   $count_sessions = "SELECT COUNT(*) FROM sessions WHERE session_id= '" . $session_id . "'";
   $result = mysql_query($count_sessions);
   if(!$result){
    throw new Exception("SQLException dataのカウントに失敗しました");
   }
   $row = mysql_fetch_row($result);
   $count = intval($row[0]);
   if($count > 0){
    $update_sessions = "UPDATE sessions "
           . "SET data='" . $session_data . "',"
           . "updated_at = now() "
           . "WHERE session_id = '" . $session_id . "'";
       fwrite($this->_fp, "write: " . $update_sessions . "\n");
    $result = mysql_query($update_sessions);
    if(!$result){
     throw new Exception("SQLException dataの更新に失敗しました");
    }
   
   }else{
    $insert_sessions  = "INSERT INTO sessions(session_id, "
              . " data," 
              . " created_at)"
                                       . "VALUES(" 
              . "'" . $session_id . "',"
              . "'" . $session_data . "',"
              . " now())";
       fwrite($this->_fp, "write: " . $insert_sessions . "\n");
    $result = mysql_query($insert_sessions);
    if(!$result){
     throw new Exception("SQLException dataの登録に失敗しました");
    }
   }
  }catch(Exception $e){
   fwrite($this->_fp, $e->getMessage()."\n");
   throw $e;
  }
  return true;
 }
 public function close()
 {
  fwrite($this->_fp, "close: "."\n");
     mysql_close($this->_db);

  return true;
 }

 public function destroy($session_id)
 {
  try{
   $session_id = mysql_real_escape_string($session_id);
   $delete_sessions = "DELETE FROM sessions WHERE session_id = '" . $session_id . "'";
   fwrite($this->_fp, "destroy: " . $delete_sessions . "\n");
   $result = mysql_query($delete_sessions);
   if(!$result){
    throw new Exception("SQLException sessionsの削除に失敗しました");
   }
  }catch(Exception $e){
   fwrite($this->_fp, $e->getMessage()."\n");
   throw $e;
  }
  
  return true;
 }

 public function gc($maxlifetime)
 {
  try{
   $gc_sessions  = "DELETE "
                    . "FROM sessions "
              . "WHERE updated_at < current_timestamp + '-" . $maxlifetime . " secs' "
        . " OR (created_at < current_timestamp + '-" . $maxlifetime . " secs' AND updated_at IS NULL)";
   fwrite($this->_fp, "gc: " . $gc_sessions . "\n");
   $result = mysql_query($gc_sessions); 
   if(!$result){
    throw new Exception("SQLException gcに失敗しました"); 
   }
  }catch(Exception $e){
   fwrite($this->_fp, $e->getMessage()."\n");
   throw $e;
  }

  return true;
 }
}
db_test.php
<?php
require_once 'Session.php';
try{
 $handler = new Session();
 session_set_save_handler($handler, true);
 session_start();
 $_SESSION["box"] = "test";
 var_dump($_SESSION);
}catch(Exception $e){
 echo $e->getMessage();
}
db_test2.php
<?php
try{
   require_once 'Session.php';
   $handler = new Session();
   session_set_save_handler($handler, true);
   session_start();
   $_SESSION["box"] = "box";
   var_dump($_SESSION);
   session_destroy();
}catch(Exception $e){
 echo $e->getMessage();
}

0 件のコメント: