2010-06-13 10 views
7

Estoy empezando con PHP, y me pregunto si existe una forma de agregar una función anónima a una instancia de clase.php Establezco una función anónima en una instancia

Por ejemplo, digamos que ...

class A{ 
    public B; 
} 

$c = new A(); 

//This is where I am getting a little confused... 
//The following wont work 

$c->B = function(){echo('HelloWorld');}; 
$c->B(); 

lo que espero que hacer es volver a utilizar la misma lengua de código en un gran número de diferentes aplicaciones, y hacerlo de modo que sólo puedo 'de intercambio -out 'y reemplazar funciones en instancias específicas.

Estoy usando php5.3 (por lo que las funciones anónimas deberían funcionar, pero no de la manera en que las estoy usando).

Muchas gracias por su tiempo !!

GK

+0

¿Puedes entrar en detalles sobre estas diferentes aplicaciones que intentas implementar? Estoy pensando que la herencia simple podría ser una mejor solución, pero sería útil contar con más información. –

+0

Posible duplicado: http://stackoverflow.com/questions/2938004/how-to-add-a-new-method-to-a-php-object-on-the-fly –

+0

GK aquí, @Tim Cooper I Estoy trabajando en un servidor para un juego en el que estoy trabajando, y el servidor estará compuesto por docenas y docenas de aplicaciones que administrarán diferentes partes del juego. Todos serán muy similares y usarán muchas de las mismas clases, sin embargo, todos necesitarán la posibilidad de ejecutar funciones personalizadas ... Resumen Lo sé, ... ¡Gracias por tu ayuda! @ dev-null-dweller Creo que tiene razón, traté de buscar este tema primero, pero obviamente no lo miré lo suficiente, ¡¡¡Gracias !! – geekay

Respuesta

9

Puede utilizar la función mágica __call para este trabajo. No es una belleza, pero funciona ..

así:

class A { 
    public $B; 

    public function __call($closure, $args) 
    { 
     call_user_func_array($this->$closure, $args); 
    } 
} 

$c = new A(); 

$c->B = function() { echo('HelloWorld'); }; 
$c->B(); 
+0

gk Aquí veré esto ... Tendré que descubrir qué es lo que hace ... ¡Muchas gracias por apuntarme en la dirección correcta! – geekay

+0

editado para revertir el downvote. Vi que publicaste la misma solución exacta que user358390 (menos una pequeña diferencia), pero no me había dado cuenta de que los tiempos eran tan cercanos, así que estoy dando el beneficio de la duda – Artefacto

1

Usted puede hacer algo en este sentido (que también trabajará con las devoluciones de llamada que no son cierres):

<?php 
class A { 
    private $fun; 
    function setFun($fun) { 
     if (!is_callable($fun)) 
      throw new InvalidArgumentException(); 
     $this->fun = $fun; 
    } 
    public function fun() { 
     call_user_func_array($this->fun, func_get_args()); 
    } 
} 

$c = new A(); 

$c->setFun(function($a) { echo('HelloWorld ' . $a);}); 
$c->fun("here"); 

lo que da HelloWorld here.

Dicho esto, también debe considerar la herencia o el decorator pattern.

4
# real ugly, but PoC... 

class a { 
    function __call($f, $x) { 
    call_user_func_array($this->$f, $x); 
    } 
} 

$a = new a; 
$a->b = function() { echo "Hello world"; }; 
$a->b(); 
4

Fwiw: tratamiento de funciones anónimas

PHP de 5.3 es entretenido. Esto no funcionará:

$c->B = function() { echo func_get_arg(0); }; 
$c->B("This fails :("); 

esto funcionará:

$c->B = function() { echo func_get_arg(0); }; 
$hilarious = $c->B; 
$hilarious("This works!"); 

Para evitar esto, es necesario utilizar un __call hackear como el que provided by Oden.

Este comportamiento puede cambiar en el futuro. El array dereferencing RFC fue recently committed to PHP's trunk, y el parche ha activado una discusión en function call chaining, cuya sintaxis puede permitir lo que está intentando hacer sin el __call hack. Lamentablemente, es proven difficult in the past para que funcionen las cadenas de llamada en funcionamiento.

+1

¿Qué hay de malo con solo usar el divertido método? – mukunda

+0

No está * mal *, solo es feo y hacky. – Charles

0

En lugar de conectar un método mágico __call en su clase, puede ejecutar el llamable directamente usando call_user_func.

class A { 
    public $b; 
} 

$c = new A(); 
$c->b = function(){echo('HelloWorld');}; 

call_user_func($c->b); // HelloWorld 

Obviamente, sería bueno para PHP proporcionar algo de sintaxis para ejecutar esto directamente.

1

Esto ya no es un problema en PHP 7;

// no error 
$result = ($this->anonFunc)(); 
$result = ($this->anonFunc)($arg1, $arg2, ...); 

Ver más sobre AST.

Cuestiones relacionadas