セッションをオブジェクトっぽくするだけのクラス

phpのセッション変数 $_SESSION に直接タッチするのをなるべく減らす目的に作った中途半端なクラス。どちらかというとSessionクラスを使うことよりも、セッションの発動を制御する処理を使うのがメインかもしれない。
アプリケーションで必ず読み込む共通動作設定ファイルを用意する。そこでセッションを有効にするスクリプトファイル名を定義して、セッションの発動をコントロールできます。

変数 $__SESSION_CLASS_CONTROL__ を宣言しなければ、Session.class.phpをコールすれば常にセッション発動(session_start())します。

<?php
/*
 * セッションを有効にするスクリプトの定義
 * 例えば、認証チェックを継続して行なうページでセッションを発動させる。
 */
static $__SESSION_CLASS_CONTROL__ = array( 'delete.php',
                                           'detail.php',
                                           'top.php' );
/*
 * $__SESSION_CLASS_CONTROL__ を定義してからSession.class.phpをコールする
 */
include_once('Session.class.php');

/*
 * セッションを有効にするページでは自動的に、
 * セッションの再生成をおこなってSessionIDを書換える
 */
if ( __IS_SESSION_CLASS_CALLED__ ) {
  if ( isset($_SESSION) ) sessionRegenerate();
}
?>

Session.class.phpの使い方

例1.セッションを始める or 値を格納する

<?php
require_once('Session.class.php');
$sess = new Session('newSession');
$sess->setVar('userInfo', $userInfoFromDB );
$sess->setVar('userAuthInfo', $authFromRequest );
$sess->setSession();
?>

例2.セッションがすでにある場合のインスタンス化と値の取り出し方

<?php
require_once('Session.class.php');
$sess = $_SESSION['newSession'];
$userInfo = $sess->getVar('userInfo');
$authInfo = $sess->getVar('userAuthInfo');
?>
  • ファンクションリスト

void sessionIsOver() : セッション終了時にコールする関数
void sessionRegenerate() : セッションidを再生成する関数

  • Sessionクラスのメソッドリスト

string getTolken() : セッションに保存したトークンを取得する。
void setVar (string $name, mixed $value) : 値をセッションオブジェクトに保存する。
mixed getVar (string $name) : 保存した値を取得する。引数は保存時のインデックス名。
string setTolken ([string $aTolken = NULL]) : 二重投稿防止用のトークンを保存。引数無しなら自動生成して戻り値で返す。
bool tolkenValidate ([string $requestTolken = NULL]) : トークンを比較する。引数がなければ$_REQUEST['sessionToken']と比較する。
void setSession () : セッションオブジェクトを実際に保存する。値を変更したら最後に必ずコールするメソッド。
void resetSession () : セッションオブジェクトをリセット(null)する。

  • Session.class.phpソース
<?php /* -*-java-*- */
/* 
 * セッションの有効無効を管理するには
 * 定数配列 $__SESSION_CLASS_CONTROL__ にスクリプト名を代入する
 * この定数が宣言されていなければ、これまで通りに使用できる。
 */
if ( isset( $__SESSION_CLASS_CONTROL__ ) ) {
    if ( in_array( basename($_SERVER['SCRIPT_FILENAME']),
		   $__SESSION_CLASS_CONTROL__ ) ) {
	define('__IS_SESSION_CLASS_CALLED__', TRUE );
    }
    else {
	define('__IS_SESSION_CLASS_CALLED__', FALSE );
    }
}
else {
    define('__IS_SESSION_CLASS_CALLED__', TRUE );
}

/* 
 * セッション制御を明示しなければ
 * このファイルを読み込んだときには必ず session_start()する。
 * 
 * 配列$__SESSION_CLASS_CONTROL__があれば
 * セッション有効時のみ session_start() する
 */
if ( __IS_SESSION_CLASS_CALLED__ ) {
    /** 
     * セッションを使う時の準備をするスクリプト
     * セッションをスタートさせるまえに、クラス定義をロードする必要がある
     * 
     * @package ya--mada
     */
    
    ini_set('session.cache_limiter', 'nocache');
    /* 
     * セッションに関する設定を、より安全方向に振る
     * セッションの設定をいじると、うまく機能しない。なぜに?
     */
    // ini_set('session.auto_start', 0 );
    // ini_set('session.bug_compat_42', 1 );
    // ini_set('session.bug_compat_warn', 1 );
    // ini_set('session.cookie_secure', 0 );
    // ini_set('session.use_cookies', 1 );
    // ini_set('session.use_only_cookies', 0 );
    // ini_set('session.use_trans_sid', 1 );
    // ini_set('session.cookie_httponly', 1 );
    
    /*
     * 単純なセッションハイジャック対策
     */
    $session_name = session_name();
    if ( isset( $_COOKIE["$session_name"] ) ) {
	$session_id = $_COOKIE["$session_name"];
	if ( !preg_match( '/[a-zA-Z,\-]+/', $session_id ) ) {
	    unset($_COOKIE["$session_name"]);
	    unset($_GET["$session_name"]);
	    unset($_POST["$session_name"]);
	}
    }
    
    /* 
     * セッション的な処理の開始
     */
    session_start();
    
    
    /**
     * function  この接続のセッションそのものを廃棄する
     * すべてのセッション情報が破棄されます
     * 
     * @access public
     */
    function sessionIsOver() {
	$_SESSION = null;
	if ( isset($_COOKIE[session_name()]) ) {
	    setcookie(session_name(), '', time()-42000, '/');
	}
	$old_id = session_id();
	$old_session_file = session_save_path()."/sess_".$old_id;
	if ( file_exists($old_session_file) ) unlink($old_session_file);
	
	return session_destroy();
    }
    
    
    /**
     * function セッションIDを付け直す
     * セッションをハイジャックを防ぎたいが、「戻る」「進む」が使えなかったり
     * 
     * @access public
     */
    function sessionRegenerate() {
	
	$tmp = $_SESSION;
	$old_id = session_id();
	
	session_destroy();
	session_start();
	session_regenerate_id(true);
	// session_id(md5(uniqid((isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''), true)));
	
	$old_session_file = session_save_path()."/sess_".$old_id;
	if ( file_exists($old_session_file) ) unlink($old_session_file);
	$_SESSION = $tmp;
    }
}


/** 
 * セッションクラス
 * 
 * セッションを始める or 値を格納する
 * <code>
 * $sess = new Session('newSession');
 * $sess->setVar('userInfo', $userInfoFromDB );
 * $sess->setVar('userAuthInfo', $authFromRequest );
 * $sess->setSession();
 * </code>
 * 
 * セッションがすでにある場合のインスタンス化と値の取り出し方。
 * <code>
 * $sess = $_SESSION['newSession'];
 * $userInfo = $sess->getVar('userInfo');
 * $authInfo = $sess->getVar('userAuthInfo');
 * </code>
 * 
 * 二重投稿防止にセッションを使う。
 * 
 * 確認画面などでの処理。
 * <code>
 * $sess = new Session('newSession');
 * $tolken_string = $sess->setTolken();
 * $sess->setSession();
 * 
 * echo $tolken_string;
 * </code>
 * $tolken_string を form の hidden属性などで次ページに渡す。
 * 
 * 実際に処理をする画面で行なう処理。
 * <code>
 * $tolken_string_from_request = $_REQUEST['sessionTolken'];
 * $sess = $_SESSION['newSession'];
 * if ( $sess->tolkenValidate($tolken_string_from_request) ) {
 *   echo "正常投稿";
 * }
 * else {
 *   echo "投稿済み?トークンが異なります。";
 * }
 * </code>
 * 
 * 
 * @todo  使い方を簡単にまとめる
 * @author	k5959k+yamada@gmail.com
 * @create	2004/11/11
 * @update      2008/12/11
 * @package     ya--mada
 */
class Session
{
    /**
     * セッション名  保存時に使用する、次ページでも同じでよろ。
     * $_SESSION['ここのお名前']
     * @access	private
     * @var	string
     */
    var $sessionName_ = null;
    
    /**
     * おもに二重投稿防止にしようするトークン
     * @access	private
     * @var	string
     */
    var $betterTolken_ = null;
    
    /**
     * セッションに格納する値を入れる配列
     * 
     * @access private
     * @var    array
     */
    var $_vars = null;
    
    /**
     * フォームフィールド
     * @access	private
     * @var	Form
     */
    var $form_ = null;
    
    
    /**
     *  Constractor Session class
     *  You have Control, session name.
     *
     */
    function session( $sessionName )
    {
	$this->sessionName_ = $sessionName;
    }
    
    /**
     * セッションオブジェクトをセッションに保存する。
     * 明示的にsetSession()を実行しないと実際に保存されないので注意が必要。
     * 
     * @access public
     */
    function setSession () {
	$_SESSION[ $this->getSessionName() ] = $this;
    }
    
    /**
     * 実際のセッション情報をnullにする
     * セッションオブジェクトが生成されていればオブジェクト内の情報は保持されています。
     * 
     * @access public
     */
    function resetSession () {
	$_SESSION[ $this->getSessionName() ] = null;
    }
    
    
    /**
     * 二重投稿防止トークンをする。引数無しなら自動で生成する。
     * 
     * @access public
     * @param  string $aTolken アプリ側でトークンを作る場合は引数を与える
     * @return string 
     */
    function setTolken( $aTolken=NULL ) {
	if ( is_null($aTolken) ) {
	    $this->betterTolken_ = md5(uniqid((isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''), true));
	} else {
	    $this->betterTolken_ = $aTolken;
	}
	return $this->betterTolken_;
    }
    
    /**
     * 二重投稿防止トークンを取得する。
     * 
     * @access public
     * @return string 設定されていなければnullを返す。
     */
    function getTolken() {
	return $this->betterTolken_;
    }
    
    
    /**
     * session に格納したトークンと、URIリクエストのトークンを比較する
     * 
     * @access public
     * @param  string $requestTolken リクエスト中に入れたトークン。
     *                省略されていれば 'sessionTolken' というリクエストを使う。
     * @return bool
     */
    function tolkenValidate( $requestTolken=NULL ) {
	
	if ( is_null($requestTolken) ) {
	    if ( !isset($_REQUEST['sessionTolken']) ) return FALSE;
	    
	    $requestTolken = $_REQUEST['sessionTolken'];
	    
	}
	
	return ($this->betterTolken_ == $requestTolken);
    }
    
    
    /**
     * セッションの名前(アプリケーション毎に?)
     * 
     * @access public
     * @param  string
     */
    function setSessionName ( $sessionName ) {
	$this->sessionName_ = $sessionName;
    }
    
    /**
     * セッションの名前(アプリケーション毎に?)
     * 
     * @access public
     * @return string
     */
    function getSessionName () {
	return $this->sessionName_;
    }
    
    
    /**
     * フォームオブジェクトをセットする
     *
     * @access public
     * @param  Form
     */
    function setForm($newForm)
    {
	$this->form_ = $newForm;
    }
    
    /**
     * フォームオブジェクトをゲットする
     * 
     * @access public
     * @return Form
     */
    function  getForm()
    {
	return $this->form_;
    }
    
    /**
     * 任意の変数をセッションに入力する
     * 
     * @access public
     * @param  string  $name  値に付けるインデックス名。同名があれば上書き。
     * @param  mixed   $value 値
     */
    function setVar( $name, $value ) {
	
	if( is_null($this->_vars) )
	    $this->_vars = array();
	
	$this->_vars = array_merge( $this->_vars, array( "$name" => $value ));
    }
    
    
    /**
     * 名前で指定した値をセッションから変数をとりだす
     * なければ NULL を返す。
     * 
     * @access public
     * @param  string $name 取得したい値のインデックス名
     * @return mixed  なければnullを返す。
     */
    function getVar( $name ) {
	return isset($this->_vars["$name"]) ? $this->_vars["$name"] : null;
    }
}
?>