2012-10-12 75 views
14

Me gustaría iterar sobre una matriz y crear dinámicamente funciones basadas en cada elemento. Mi pseudocódigo:Crear dinámicamente funciones de clase PHP

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

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

¿Cómo debo hacer esto?

+4

¿Puedo preguntar por qué desea crear este funciona – Baba

+0

PHP no funciona así. – hakre

+0

Agregar demasiada dinámica puede hacer que un programa sea ilegible, lo que es equivalente a no serlo. ¿Puedes entrar en detalles de lo que tienes y lo que quieres obtener? – Sven

Respuesta

22

En lugar de "crear" funciones, puede utilizar el método mágico __call(), de modo que cuando llame a una función "inexistente", puede manejarlo y realizar la acción correcta.

Algo como esto:

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

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

A continuación, puede llamar a:

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

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

EDITAR: Si está usando PHP 5.3+, en realidad se puede haz lo que tratas de hacer en tu pregunta!

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

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

Esto funciona, excepto que no se puede llamar directamente $a->one(), es necesario save it as a variable.

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

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

+0

@NullUserException: Gracias por agregar el hecho de que '__call()' es un "método mágico". –

+0

También puede usar la función mágica '__get()' para llamar a funciones de cierres/devoluciones de llamada luego :, ver [Método de creación dinámica de instancias en PHP] (http://stackoverflow.com/questions/3231365/dynamically-create-instance- method-in-php) - Si realmente crees que '__call()' o '__get()' es lo que se ha pedido, por favor sugiere una pregunta existente como un duplicado. – hakre

+1

¿Cómo puede PHP docblock esto para que el editor no advierta sobre "funciones no existentes"? – Kyslik

-2

No estoy seguro sobre el uso en su caso, se puede utilizar create_function para crear funciones anónimas.

+2

No creo que 'create_function' se pueda usar para crear métodos, y creo que es aconsejable evitarlo de todos modos. El método mágico '__call', como lo propone @RockedHazmat es una mejor opción. – 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); 
} 

El resultado del ejemplo sería:

Test: one 
Test: two 
Test: three 
+0

¿hay alguna manera de evitar el '$ a [0]' y simplemente tener '$ a'? – duck

+0

@duck class MethodTest { public function __call ($ name, $ arguments) { echo "" . "Método:". $ Nombre. "\ N" . (! empty ($ arguments)? "Parámetros:".implode (',', $ arguments): "¡Sin parámetro!"). "\norte"; } } $ obj = new MethodTest; $ obj-> ExecTest ('par 1', 'par 2', 'otros ...'); $ obj-> ExecTest(); – q81

Cuestiones relacionadas