シングルトンバージョン5.3から5.2

挑戦する



一般に、プロジェクトに提供されているホスティングでは、PHPバージョンが5.2で、プロジェクト自体が5.3で記述されているという状況がありました。 PHPを使用するすべての人は、バージョン5.3で遅延静的バインディングを使用して取得したクラス名にアクセスできるようになったことを知っています。



例:

<?php class Singleton { static $instances = Array(); private function __construct() {} private function __clone() {} private function __wakeup() {} static function model(){ $class = get_called_class(); if (!isset(self::$instances[$class])) { self::$instances[$class] = new $class(); } return self::$instances[$class]; } }
      
      





そして今、このクラスの子孫はSingletonになります。

 class Test extends Singleton { public function say(){ return 'Hi Habr!'; } } echo Test::model()->say();
      
      





この手法は、バージョン5.3の新しいget_called_class関数により可能になりました。 以前のバージョンではこれが機能しないことは明らかです。 しかし、コードがすでに記述されていて、PHPの最新バージョンが利用できない場合はどうでしょうか?



解決策



解決策は、ホスティングを変更するか、PHPの最新バージョンをインストールすることです:)。 しかし、例えば、今ではこれが不可能で、プロジェクトが機能するはずだという状況があったので、外に出なければなりませんでした。

 <?php if(!function_exists('get_called_class')) { function get_called_class() { $obj = false; $backtrace = debug_backtrace(); foreach($backtrace as $row){ if($row['function'] == 'call_user_func'){ $obj = explode('::', $backtrace[2]['args'][0]); $obj = $obj[0]; break; } } if(!$obj){ $backtrace = $backtrace[1]; $file = file_get_contents($backtrace["file"]); $file = explode("\n", $file); for($line = $backtrace["line"] - 1; $line > 0; $line--) { preg_match("/(?<class>\w+)::(.*)/", trim($file[$line]), $matches); if (isset($matches["class"])){ return $matches["class"]; } } throw new Exception("Could not find"); } return $obj; } } class Singleton { static $instances = Array(); private function __construct() {} private function __clone() {} private function __wakeup() {} static function model(){ $class = get_called_class(); if (!isset(self::$instances[$class])) { self::$instances[$class] = new $class(); } return self::$instances[$class]; } }
      
      





問題の一時的な解決策として非常に適しています。 さて、変数を使用してクラスを参照する機能に関連する問題を解決するには:

 $class_name::model();
      
      





に置き換え:

 call_user_func($class_name. '::model');
      
      





それだけです。 ご清聴ありがとうございました。



All Articles