SessionBehaviorを作ったわけ

CakePHPのSessionの利用方法は、基本的に以下の二つです。

  • ControllerからSessionComponentを使う($this->Session)
  • viewからSessionHelperを使う($session->hoge())

基本的にMVCの理念から、ControllerとView以外でSessionを利用する機会はありません。
しかしデバッグの為や、通常しないようなハックをしたい場合などは”どこでも”Sessionが使えるようになると便利です。

自分もオリジナルのdebug関数を実装するとき、このようなことを思いつき、APIやコードを眺めると、以下のような方法に落ち着きました。

  • CakeSessionのインスタンスを作る
  • 関数が呼び出される度にインスタンスが生成されてよろしくないので、ClassRegistryに登録する
  • 呼ばれる場所によってはセッションがスタートしていないので、その判定もつける

こうなってくると、案外簡単な方法ではありません。
事実、CakePHP-jpのフォーラムで質問に答えたときも、ごちゃごちゃしてて嫌!と一蹴されました。

MVCから外れると途端に不親切になるのはCakePHPの良くないところだと個人的に思います。(そういう人はCakePHP以外を使えって?その通りかもね!

んなわけで、とりあえずModelからSessionを呼べるようにと、Behaviorを作りました。
ところで書いてて思ったんだけど、これ静的なクラスか関数に落とし込めばどこでも読めるんじゃね?と思った・・・

・・・コード見て、適当にやってね(ぇー

とりあえず一例:

<?php
class SessionManager{
	function &get($start = true , $base = null){
		$session = null;
		if(ClassRegistry::isKeySet('CakeSession')){
			$session = ClassRegistry::getObject('CakeSession');
		}else{
			App::import('Core','CakeSession');
			$session = new CakeSession($base,$start);
			
			ClassRegistry::addObject('CakeSession',$session);
		}
		
		if($session === null){
			return $session;
		}
		
		if($start && !$session->started()){
			$session->start();
		}
		
		return $session;
	}
}
<?php
function &getSession($start = true , $base = null){
	$session = null;
	if(ClassRegistry::isKeySet('CakeSession')){
		$session = ClassRegistry::getObject('CakeSession');
	}else{
		App::import('Core','CakeSession');
		$session = new CakeSession($base,$start);
		
		ClassRegistry::addObject('CakeSession',$session);
	}
	
	if($session === null){
		return $session;
	}
	
	if($start && !$session->started()){
		$session->start();
	}
	
	return $session;
}