2010-09-24 10 views
7

Sto usando php 5.2.6. Ho un modello di strategia e le strategie hanno un metodo statico. Nella classe che implementa effettivamente una delle strategie, ottiene il nome della classe di strategia da istanziare. Tuttavia, ho voluto chiamare uno dei metodi statici prima di esemplificazione, in questo modo:Impossibile chiamare il metodo statico dalla classe come nome di variabile?

$strNameOfStrategyClass::staticMethod(); 

ma dà 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) 

Opererebbe in 5.3?

risposta

11

Sì. Che la sintassi è stato introdotto in 5.3

Per risolvere per < = 5.2, è possibile utilizzare call_user_func:

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

o call_user_func_array:

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

Ma su un'altra nota, quello che si sta cercando di non ha davvero senso ...

Perché avere come funzione statica? Il tuo costruttore in implementation si aspetta comunque un oggetto (è ciò che sta cercando strategyInterface $strategy). Passare una stringa non funzionerà, poiché le stringhe non implementano le interfacce. Quindi quello che vorrei fare, è rendere l'interfaccia non statico, e poi fare qualcosa di simile:

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

Poi, nel costruttore:

$strFormat = $strategy->getFormatString(); 

Oppure, se si vuole veramente ancora quel metodo per sia statica che si possa fare:

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

Oh, e = & new SYNAX è deprecated (e non fa quello che pensi lo fa comunque).

+1

+1 per come affrontare il problema del suggerimento del tipo –

+0

Avere una scoreggia del cervello oggi: PI non vuole passare un oggetto istanziato alla classe di implementazione, perché voglio istanziarlo su tutta la linea, dopo che la classe di implementazione ha creato alcuni dati che la strat egy ha bisogno. Penso che avrò comunque bisogno di 'call_user_func_array()' - grazie per il grande codice! – user151841

+0

Si noti che questo tipo di opere funziona solo in 5.3. Puoi fare "$ foo :: staticMethod()" ma non puoi fare "$ this-> foo = new Whatever(); $ this-> foo :: staticMethod()". –

0

Tipo hinting sta per darvi alcuni problemi:

Argomento 1 passata a realizzazione :: __ construct() deve implementare l'interfaccia strategyInterface, stringa di dato

+0

Hm, cervello scoreggia stamattina. Perché il mio php non mi ha dato quell'errore? – user151841

+0

@ user151841 - Perché T_PAAMAYIM_NEKUDOTAYIM inatteso viene rilevato al momento della compilazione, quindi si stava ricevendo quell'errore ... Ho risolto il problema con call_user_func() prima ancora di provare a eseguire il codice, e ho ottenuto il secondo errore, che è un errore di runtime. –

Problemi correlati