2010-07-12 18 views
8

me gustaría ser capaz de crear dinámicamente un método de instancia dentro de una clase constructor de este modo:dinámicamente crear instancia Método en PHP

class Foo{ 
    function __construct() { 
     $code = 'print hi;'; 
     $sayHi = create_function('', $code); 
     print "$sayHi"; //prints lambda_2 
     print $sayHi(); // prints 'hi' 
     $this->sayHi = $sayHi; 
    } 
} 

$f = new Foo; 
$f->sayHi(); //Fatal error: Call to undefined method Foo::sayHi() in /export/home/web/private/htdocs/staff/cohenaa/dev-drupal-2/sites/all/modules/devel/devel.module(1086) : eval()'d code on line 12 

El problema parece ser que el objeto función lambda_2 no está recibiendo obligado a $ this dentro del constructor.

Cualquier ayuda es apreciada.

+0

Es posible que desee limpiar los errores en el código del constructor. – Gordon

Respuesta

18

está asignando la función anónima a una propiedad , pero luego intenta llamar a un método con el nombre de la propiedad. PHP no puede desreferenciar automáticamente la función anónima de la propiedad. El siguiente trabajo

class Foo{ 

    function __construct() { 
     $this->sayHi = create_function('', 'print "hi";'); 
    } 
} 

$foo = new Foo; 
$fn = $foo->sayHi; 
$fn(); // hi 

Puede utilizar el método mágico __call para interceptar llamadas de método válido para ver si hay una propiedad que ocupen una función de devolución de llamada/anónima sin embargo:

class Foo{ 

    public function __construct() 
    { 
     $this->sayHi = create_function('', 'print "hi";'); 
    } 
    public function __call($method, $args) 
    { 
     if(property_exists($this, $method)) { 
      if(is_callable($this->$method)) { 
       return call_user_func_array($this->$method, $args); 
      } 
     } 
    } 
} 

$foo = new Foo; 
$foo->sayHi(); // hi 

A partir de PHP5.3 , también se pueden crear con Lambdas

$lambda = function() { return TRUE; }; 

Ver el PHP manual on Anonymous functions para mayor referencia.

+3

Para completar, el uso de create_function de esta manera creará una función lamda en el espacio global cada vez que se construye la clase y permanecerá en la memoria sin los beneficios de la recolección de basura (cuando el objeto está desarmado, por ejemplo). Funcionará, pero úselo con cuidado. – webbiedave

+2

Para una mayor completud, 'create_function' no crea nada como un lambda; es básicamente un' eval' glorificado, que crea una función llamada tal que ninguna función "real" podría entrar en conflicto. A menos que necesite compatibilidad con PHP <5.3, se debe evitar siempre que sea posible. – IMSoP

3

Puede utilizar el método mágico __call para emplear métodos de instancia en tiempo de ejecución.

class Foo 
{ 
    public function __call($name, $args) 
    { 
     if ($name == 'myFunc') { 
      // call myFunc 
     } 
    } 
} 
Cuestiones relacionadas