2009-09-08 2 views
0

Мне нужно вызвать статическую функцию из объекта с использованием дизайна Singleton, но с использованием переменной в качестве имени класса.PHP: использовать имя переменной для вызова статической функции на Singleton Object

Лучший способ, $class::getInstance();, доступен только в PHP 5.3, а другим способом, который я нашел, call_user_func(array($class, 'getInstance'));, приводит к нарушению максимального времени выполнения. Кто-нибудь знает, почему это происходит, или способ для этого работать/обходной путь?

Я знаю, что это не лучший способ для вещей, и дизайн шаблона Singleton не будет моим первым выбором, но, к сожалению, это не зависит от меня.

Заранее спасибо всем, кто вносит свой вклад :)

я включаю остальную часть кода Подключайтесь:

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 от http://www.septuro.com/ для кода - слишком сложный, чтобы быть любым из моих!).

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(); 
    } 
} 

Перейду ко всему моему коду еще раз, так как там где-то должна быть петля. Назад к чертежной доске захожу :(

+1

не использовать ссылочный оператор (&) с классами в PHP5, это устарело (хотя это не спасет вашу проблему-i guess) – knittl

+0

Вероятно, это скорее опечатка, чем источник вашей проблемы, но ваш метод 'loadLibrary' принимает' $ lib' как аргумент, но ссылается на '$ class' в коде. –

ответ

2

Вы должны начать с определения того, что она принимает вас, что в бесконечный цикл. имеет ли ваш конструктор (someLibrary::__construct()) есть код, который прямо/косвенно вызывает Library::getInstance(), например?

EDITget_called_class() был введен в PHP 5.3, поэтому, если ваш код действительно работает, вы уже работаете. 5.3

0

вы могли бы попытаться решить эту проблему с eval()

Чтобы получить Вам идею:.

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