2010-09-24 5 views
7

Я использую php 5.2.6. У меня есть шаблон стратегии, и стратегии имеют статический метод. В классе, который фактически реализует одну из стратегий, он получает имя класса стратегии для создания экземпляра. Тем не менее, я хотел бы назвать один из статических методов, прежде чем конкретизации, например:Нельзя вызвать статический метод из класса как имя переменной?

$strNameOfStrategyClass::staticMethod(); 

но это дает T_PAAMAYIM_NEKUDOTAYIM.

$> cat test.php 

<? 

interface strategyInterface { 
     public function execute(); 
     public function getLog(); 
     public static function getFormatString(); 
} 


class strategyA implements strategyInterface { 
     public function execute() {} 
     public function getLog() {} 
     public static function getFormatString() {} 
} 

class strategyB implements strategyInterface { 
     public function execute() {} 
     public function getLog() {} 
     public static function getFormatString() {} 
} 

class implementation { 
     public function __construct(strategyInterface $strategy) { 
       $strFormat = $strategy::getFormatString(); 
     } 
} 

$objImplementation = & new implementation("strategyB") ; 

$> php test.php 

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in /var/www/test.php on line 24 

$> php -v 

PHP 5.2.6-1+lenny9 with Suhosin-Patch 0.9.6.2 (cli) (built: Aug 4 2010 03:25:57) 

Будет ли это работать в 5.3?

ответ

11

Да. Этот синтаксис был введен в 5,3

Чтобы обойти для < = 5.2, вы можете использовать call_user_func:

call_user_func(array($className, $funcName), $arg1, $arg2, $arg3); 

или call_user_func_array:

call_user_func_array(array($className, $funcName), array($arg1, $arg2, $arg3)); 

Но на другой ноте, что вы пытаетесь do на самом деле не имеет смысла ...

Почему у него статическая функция? Ваш конструктор в implementation ожидает объект в любом случае (это то, что ищет strategyInterface $strategy). Передача строки не будет работать, поскольку строки не реализуют интерфейсы. Так что я хотел бы сделать, это сделать интерфейс, не статична, а затем сделать что-то вроде:

$strategy = new StrategyB(); 
$implementation = new Implementation($strategy); 

Затем в конструкторе:

$strFormat = $strategy->getFormatString(); 

Или, если вы действительно все еще хотите этот метод для статическими вы могли бы сделать:

$strFormat = call_user_func(array(get_class($strategy), 'getFormatString')); 

О, и = & new synax является deprecated (и не делать то, что вы думаете, он делает так или иначе).

+1

+1 для того, как справиться с проблемой типа намекания –

+0

Имея мозговой пердит сегодня: PI не хочет передавать экземпляр-объект для класса реализации, потому что я хочу создать его на линии, после того, как класс реализации создал некоторые данные, которые страт потребности. Я думаю, мне понадобится 'call_user_func_array()' anyway - спасибо за отличный код! – user151841

+0

Обратите внимание, что это всего лишь работа в 5.3. Вы можете сделать «$ foo :: staticMethod()», но вы не можете сделать «$ this-> foo = new Whatever(); $ this-> foo :: staticMethod()». – 2012-12-21 23:37:27

0

Тип намекая собирается дать вам некоторые проблемы:

Аргумент 1 переданную реализации :: __ конструкт() должен реализовать интерфейс strategyInterface, строка, заданная

+0

Хм, мозг пердеть сегодня утром. Почему мой php не дал мне эту ошибку? – user151841

+0

@ user151841 - поскольку во время компиляции обнаружен неожиданный T_PAAMAYIM_NEKUDOTAYIM, так что вы получили эту ошибку ... Я исправил это с помощью call_user_func(), прежде чем даже попытался запустить код, и получил вторую ошибку, которая является ошибкой во время выполнения. –

Смежные вопросы