2010-07-12 11 views
8

mi piacerebbe essere in grado di creare dinamicamente un metodo di istanza all'interno di una classe costruttore in questo modo:dinamicamente Creare Metodo grado nella 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 

Il problema sembra essere che l'oggetto funzione lambda_2 non è sempre vincolato a $ questo all'interno del costruttore.

Qualsiasi aiuto è apprezzato.

+0

Si consiglia di pulire gli errori nel codice del costruttore. – Gordon

risposta

18

si sta assegnando la funzione anonima a un immobile, ma poi tenta di chiamare un metodocon il nome della proprietà. PHP non può delegare automaticamente la funzione anonima dalla proprietà. Di seguito lavorerà

class Foo{ 

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

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

È possibile utilizzare il metodo magico __call per intercettare il metodo non valida chiamate per vedere se c'è una proprietà in possesso di un funzione di callback/anonima però:

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 

Come di PHP5.3 , è anche possibile creare lambda con

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

Vedere la PHP manual on Anonymous functions per ulteriore riferimento.

+3

Per completezza, l'utilizzo di create_function in questo modo creerà una funzione lamda nello spazio globale ogni volta che la classe viene costruita e rimarrà in memoria senza i vantaggi della garbage collection (quando l'oggetto non è impostato, ad esempio). Funzionerà, ma usalo con cura. – webbiedave

+2

Per ancora più completezza, 'create_function' non crea nulla come un lambda - è fondamentalmente un 'eval' glorificato, che crea una funzione denominata tale che nessuna funzione" reale "potrebbe essere in conflitto. A meno che non sia necessaria la compatibilità con PHP <5.3, dovrebbe essere evitato laddove possibile. – IMSoP

3

È possibile utilizzare il metodo magico __call per utilizzare i metodi di istanza di runtime.

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