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; } } ?>