2012-10-12 16 views
14

Mi piacerebbe eseguire un'iterazione su un array e creare dinamicamente funzioni basate su ciascun elemento. La mia pseudocodice:Creare dinamicamente le funzioni di classe

$array = array('one', 'two', 'three'); 

foreach ($array as $item) { 
    public function $item() { 
     return 'Test'.$item; 
    } 
} 

Come devo andare a fare questo?

+4

Posso chiedere perché si vuole creare questa funziona – Baba

+0

PHP non funziona così. – hakre

+0

L'aggiunta di troppa dinamica può rendere illeggibile un programma, il che equivale a non mantenibile. Puoi entrare nei dettagli di ciò che hai e di ciò che vuoi ottenere? – Sven

risposta

22

Invece di "creare" funzioni, è possibile utilizzare il metodo magico __call(), in modo che quando si chiama una funzione "inesistente", è possibile gestirlo e fare la giusta azione.

Qualcosa di simile a questo:

class MyClass{ 
    private $array = array('one', 'two', 'three'); 

    function __call($func, $params){ 
     if(in_array($func, $this->array)){ 
      return 'Test'.$func; 
     } 
    } 
} 

quindi è possibile chiamare:

$a = new MyClass; 
$a->one(); // Testone 
$a->four(); // null 

DEMO: http://ideone.com/73mSh

EDIT: Se si sta utilizzando PHP 5.3+, è effettivamente possibile fai quello che stai cercando di fare nella tua domanda!

class MyClass{ 
    private $array = array('one', 'two', 'three'); 

    function __construct(){ 
     foreach ($this->array as $item) { 
      $this->$item = function() use($item){ 
       return 'Test'.$item; 
      }; 
     } 
    } 
} 

Questo funziona, solo che non si può chiamare $a->one() direttamente, è necessario save it as a variable.

$a = new MyClass; 
$x = $a->one; 
$x() // Testone 

DEMO: http://codepad.viper-7.com/ayGsTu

+0

@NullUserException: Grazie per aver aggiunto il fatto che '__call()' è un "metodo magico". –

+0

Puoi anche usare la funzione magica '__get()' per chiamare le funzioni closures/callbacks quindi :, vedi [Dynamically Create Instance Method in PHP] (http://stackoverflow.com/questions/3231365/dynamically-create-stance- method-in-php) - Se pensi davvero che '__call()' o '__get()' sia ciò che è stato chiesto, ti preghiamo di suggerire una domanda esistente come duplicato. – hakre

+1

Come si può scrivere in PHP questo documento in modo che l'editor non avvisi su "funzioni non esistenti"? – Kyslik

-2

Non sono sicuro circa l'utilizzo nel tuo caso, è possibile utilizzare create_function per creare funzioni anonime.

+2

Non penso che 'create_function' possa essere usato per creare metodi, e penso che sia saggio evitarlo comunque. Il metodo magico '__call', come proposto da @RockedHazmat è un'opzione migliore. – GolezTrol

2
class MethodTest 
{ 
    private $_methods = array(); 

    public function __call($name, $arguments) 
    { 
     if (array_key_exists($name, $this->_methods)) { 
      $this->_methods[$name]($arguments); 
     } 
     else 
     { 
      $this->_methods[$name] = $arguments[0]; 
     } 
    } 
} 

$obj = new MethodTest; 

$array = array('one', 'two', 'three'); 

foreach ($array as $item) 
{ 
    // Dynamic creation 
    $obj->$item((function ($a){ echo "Test: ".$a[0]."\n"; })); 
    // Calling 
    $obj->$item($item); 
} 

Il precedente esempio visualizzerà:

Test: one 
Test: two 
Test: three 
+0

c'è un modo per aggirare il '$ a [0]' e avere solo '$ a'? – duck

+0

classe @duck MethodTest { funzione pubblica __call ($ nome, $ argomenti) { echo "" . "Metodo:". $ Name. "\ N" . (! empty ($ argomenti)? "Parametri:".implode (',', $ argomenti): "Nessun parametro!"). "\ N"; } } $ obj = new MethodTest; $ obj-> ExecTest ('par 1', 'par 2', 'others ...'); $ obj-> ExecTest(); – q81

Problemi correlati