2010-04-27 4 views
12

Es siempre me molestó una función recursiva debe nombrarse, cuando una clase instanciada puede utilizar $this y un método estático puede utilizar self etc.¿Puede hacer que una función PHP sea recursiva sin repetir su nombre?

¿Hay una manera similar a hacer esto en una función recursiva sin nombrarlo de nuevo (solo para reducir el mantenimiento)?

Obviamente podría usar call_user_func o la constante __FUNCTION__ pero preferiría algo menos feo.

+2

+1 Realmente TRB pregunta ... ¿Por qué es –

+5

'__FUNCTION__' feo? Parece ser una muy buena manera de lograr lo que quieres ... –

+0

@Felix porque probablemente será necesario agregarlo a 'call_user_func' o con' eval'. Prefiero algo como 'self :: ($ var)' – alex

Respuesta

9

Puede hacer uso de variable functions y declarar una variable con el nombre de la función al comienzo de su función (o donde sea). No hay necesidad de call_user_func:

function test($i) { 
    $__name = __FUNCTION__; 
    if($i > 5) { 
     echo $i. "\n"; 
     $__name($i-1); 
    } 
} 

No se olvide que el uso del nombre de la función real de es probablemente más fácil de leer para otras personas :)
(al menos proporcionan un comentario por qué se hace esto)


actualización:
Como @Alix menciona en su comentario, que podría ser útil para declarar $__name como static. De esta forma, el valor no se asigna una y otra vez a la variable.

+0

Olvidé esos. Eso se ve un poco mejor que 'call_user_func_array()'. Gracias +1 – alex

+0

+1, eso es hacer trampa! = P –

+0

Estoy de acuerdo con su último punto. Sin embargo, creo que * debería * poder cambiar el nombre de una función sin interrumpir las llamadas recursivas. Aunque me doy cuenta de que cambiar los nombres de las funciones interrumpe cualquier llamada a otra parte. ¡Supongo que es por eso que debes elegir nombres de funciones realmente buenos desde el principio! – alex

5

No sé por qué esto es feo:

return call_user_func_array(__FUNCTION__, func_get_args()); 

Versus:

return call_user_func_array('someFunction', func_get_args()); 

Usted todavía tendrá que utilizar call_user_func_array() si usted está mirando para reducir el mantenimiento (si su las funciones tienen [mucho/un número diferente] de argumentos).

Aparte de eso I don't see another way. También un método estático no puede referenciarse utilizando self::, solo a su clase. También necesitaría usar la constante mágica __METHOD__ para hacer eso.

+1

Con respecto a 'self ::', eso es lo que quise decir. Puedes acceder a otros métodos en esa misma clase con él. Solo pensé que se veía feo comparado con algo simple como 'self'. – alex

+0

Gracias por su respuesta Alix +1 – alex

+0

@alex: ¡Gracias, no hay problema! =) –

0

Para aquellos de ustedes que quieren hacer esto dentro de un método estático:

forward_static_call(array('self', __METHOD__), $arg1, $arg2, $etc); 

esta manera, si se cambia el nombre del método que no tiene que preocuparse de cambiar todas las llamadas de recursividad dentro de ella también.

2
function anyfunc() { 
    __FUNCTION__(); 
} 

si se utiliza en clase:

protected function anymethod() { 
    $this->{__FUNCTION__}(); 
} 
0
function self(){ 
    return call_user_func_array(debug_backtrace()[1]['function'], func_get_args()); 
} 

function test($i) { 
    if($i) { 
     echo "$i<br>\n"; 
     self($i-1); 
    } 
} 
test(5); 
Cuestiones relacionadas