PHP:使用变量名称在Singleton Object上调用静态函数

时间:2009-09-08 11:43:03

标签: php class static singleton

我需要使用Singleton设计从对象调用静态函数,但是使用变量作为类名。

最好的方法$class::getInstance();仅在PHP 5.3中可用,而我找到的另一种方式call_user_func(array($class, 'getInstance'));会导致最大的执行时间被破坏。有谁知道为什么会发生这种情况,或者为此工作/解决方法?

我知道这不是完成任务的最佳方式,单身人士的设计模式不是我的首选,但不幸的是,这不取决于我。

提前感谢任何有贡献的人:)

我包含所涉及的其余代码:

abstract class Library
 {
  protected function __construct(){}
  final private function __clone(){}

  final public static function &getInstance()
   {
    static $libs = array();
    $lib = get_called_class();
    if(!isset($libs[$lib])) $libs[$lib] = new $lib();
    return $libs[$lib];
   }

 }

public function &loadLibrary($lib)
 {
  // Filter $lib, and load the library class file...
  // Following only works in PHP 5.3
  //   return $lib::getInstance();
  // Following results in maximum execution time being breached.
   return call_user_func(array($lib, 'getInstance'));
  }
}

$someLibrary =& loadLibrary('someLibrary');

someLibrary.php:

class someLibrary extends Library
 {
  protected function __construct(){}
  // Code...
 }

Soulmerge提出一个有效的观点,说get_called_class()仅在PHP 5.3中,因此我必须使用它,但是,我只是像往常一样欺骗我的方式(感谢Chris Webb来自{ {3}}代码 - 太复杂了,不能成为我自己的代码!)。

if(!function_exists('get_called_class'))
 {
  class classTools
   {
    static $i = 0;
    static $fl = null;
    static function get_called_class()
     {
      $bt = debug_backtrace();
      if(self::$fl == $bt[2]['file'].$bt[2]['line']) self::$i++;
      else {
       self::$i = 0;
       self::$fl = $bt[2]['file'].$bt[2]['line'];}
      $lines = file($bt[2]['file']);
      preg_match_all('/([a-zA-Z0-9\_]+)::'.$bt[2]['function'].'/', $lines[$bt[2]['line']-1], $matches);
      return $matches[1][self::$i];
     }
   }
  function get_called_class()
   {
    return classTools::get_called_class();
   }
 }

我将再次查看我的所有代码,因为某处必须有一个循环。回到绘图板我去了:(

2 个答案:

答案 0 :(得分:2)

您应该首先确定将您带入无限循环的内容。您的构造函数(someLibrary::__construct())是否有任何直接/间接调用Library::getInstance()的代码,例如?

在PHP 5.3中引入了

EDIT get_called_class(),因此,如果您的代码确实有效,那么您已经在运行5.3

答案 1 :(得分:0)

您可以尝试使用eval()解决此问题。

为了你的想法:

$theVar = "relvantClassName";
$someObject = eval($theVar::getInstance());
$result = $someObject->performAction();