PHP4でSingletonパターンを実現する。

staticが使えるなんて知らなかった・・・
目からうろこです。
でも、どーもバグがあるようなので推奨されない見たいですね。
Globalでもいいんですが、そっちもバグがある。
だったら”どうせなら綺麗に”ってつもりで作って見ました。


このSingletonAdapterクラスは既存のクラスをSingletonにしてくれるAdapterの役割ももっています。
必ずSingleton::factoryから呼ばれると言う前提で組まれています。
Globalを使うと、この制約から解放出来ますが
その代わり、何処からでも変数を変えられてしまうと言う恐れがあります。

<?php

class SingletonAdapter 
{

	function & SingletonAdapter($mode,$instanceName,$scopeArr=""){
		return $this->factory($mode,$instanceName,$scopeArr);
	}

	function & factory($mode,$instanceName,$scopeArr=""){

		// 肝
		static $factory_ = array();

		// モードによって呼び出すメソッドを切り替える
		$mode = $mode."Instance";
		// factoryとインスタンス名を渡して、factoryとメソッド固有の実行結果を返してもらう。
		$res = SingletonAdapter::$mode($factory_,$instanceName,$scopeArr);

		// 戻ってきたfactoryで上書き
		$factory_ = $res['factory'];

		// resの内容に応じてreturnを可変
		if($res['object' ]) return $factory_[$instanceName];
		if($res['boolean']) return $res['boolean'];
	}

	function & createInstance(&$factory_,$instanceName,$scopeArr=""){

		$res = array();

		if(!$factory_[$instanceName]){
			// factoryにinstanceNameがまだ存在しなければ作成
			$scope = "";
			foreach($scopeArr as $key=>$val){
				if(!$val){
					$scope .= "\"\"";
				}else{
					// 固有の変数にValをしまい直す。
					eval("\$val_".$key." = \$val;");
					$scope .= "\$val_".$key;
				}
				$scope .= ",";
			}
			// 最後の","を捨てる。
			$scope = substr($scope,0,-1);
			eval("\$factory_[\$instanceName] = new ".$instanceName."(".$scope.");");
		}

		$res["object" ] = true;
		$res["factory"] = $factory_;
		return $res;
	}

	function & initInstance(&$factory_,$instanceName,$dumy){

		$res = array();

		unset($factory_[$instanceName]);

		$res["factory"] = $factory_;
		return $res;
	}

	function & isInstance(&$factory_,$instanceName,$dumy){

		$res = array();

		if(!$factory_[$instanceName]){
			$result = false;
		}else{
			$result = true;
		}

		$res["boolean"] = $result;
		$res["factory"] = $factory_;
		return $res;
	}

}

?>


参考URL:http://php.s3.to/man/function.ini-set.html