2009-10-27 25 views
50

Este código produce el resultado como 56.Función dentro de una función.?

function x ($y) { 
    function y ($z) { 
     return ($z*2); 
    } 

    return($y+3); 
} 

$y = 4; 
$y = x($y)*y($y); 
echo $y; 

Alguna idea de lo que está pasando en el interior? Estoy confundido.

+18

Suena como una pregunta de tarea, pero sigue siendo una buena pregunta jaja. – hobbes3

Respuesta

81

X retornos (valor 3), mientras que los retornos Y (valor a * 2)

Dado un valor de 4, esto significa (4+3) * (4*2) = 7 * 8 = 56.

Aunque las funciones no están limitados en su alcance (lo que significa que usted puede de manera segura 'nido' definiciones de función), este ejemplo particular es propenso a errores:

1) No se puede llamar y() antes de llamar x(), porque la función y() no se definirá hasta que x() se haya ejecutado una vez.

2) Llamar a x() dos veces causará que PHP función y() redeclarar, lo que lleva a un error fatal:

Fatal error: Cannot redeclare y()

La solución a tanto sería dividir el código, por lo que ambas funciones se declaran independientes el uno otro:

function x ($y) 
{ 
    return($y+3); 
} 

function y ($z) 
{ 
    return ($z*2); 
} 

Esto también es mucho más legible.

+51

Otra diferencia es que si tiene la función y dentro de la función x, y llama a la función x dos veces, obtendrá un error para volver a declarar la función y. (Si realmente necesita esto, debe rodear la función y con una comprobación de si (function_exists ('y')) {...) –

+3

@Eugene M: Nunca lo supe ... Gracias por señalarlo! (Solo lo probé yo mismo, después de redirigir tu comentario.) – Duroth

+3

"lo que significa que puedes 'anidar' de forma segura las definiciones de función, al mismo tiempo que puedes llamarlas a cualquier parte del archivo" - esa es una propiedad de lenguaje horrible. – Michael

25
(4+3)*(4*2) == 56 

Tenga en cuenta que PHP no es realmente compatible con "funciones anidadas", como se define solo en el ámbito de la función principal. Todas las funciones se definen globalmente. Vea el docs.

+0

Gracias, por lo que no se llama a la función interna. – Posto

+2

Por supuesto que sí, eso es lo que da como resultado la parte '(4 * 2)'. –

+1

Cuando se llama a X, la función interna se define, no se llama. Por lo tanto, el resultado. Esa es la parte peluda sobre las funciones en funciones =) – mauris

3

Su consulta está haciendo 7 * 8

x(4) = 4+3 = 7 y y(4) = 4*2 = 8

lo que sucede es cuando la función de x se llamó crea función y, no se ejecuta la misma.

+1

Solo quería agregar que esta no es una buena práctica. También notará que si usa $ y = y ($ y) * x ($ y); que el código morirá porque x no ha sido creado. Codificar de esta manera solo generará errores y confusión. –

+0

sí, eso es cierto; Personalmente, solo he usado esto una vez en la práctica para buscar diferentes estilos de citas mágicas. aunque eso estaba en una instrucción if en lugar de una función() –

14

No estoy seguro de lo que el autor de ese código quería lograr. Definir una función dentro de otra función NO significa que la función interna solo sea visible dentro de la función externa. Después de llamar a x() la primera vez, la función y() también estará en alcance global.

+4

+1 Esa última oración responde la pregunta de manera muy sucinta. – GZipp

+2

Además, definir y() dentro de x() significa que x() solo se puede llamar una vez. Obtendrá el error fatal "función ya definida" al llamar a x() por segunda vez. –

5

Es posible definir una función desde dentro de otra función. la función interna no existe hasta que se ejecuta la función externa.

echo function_exists("y") ? 'y is defined\n' : 'y is not defined \n'; 
$x=x(2); 
echo function_exists("y") ? 'y is defined\n' : 'y is not defined \n'; 

salida

y no se define

Y se define

cosa simple no se puede llamar función y antes de ejecutar x

6

Este es el concepto útil para la recursividad y sin estática propiedades, referencia, etc .:

function getReqursiveItems($id){ 
    $allItems = array(); 

    function getItemms($parent_id){ 
     return DB::findAll()->where('`parent_id` = $parent_id'); 
    } 

    foreach(getItems($id) as $item){ 
     $allItems = array_merge($allItems, getItems($item->id)); 
    } 

    return $allItems; 
} 
+0

¿Explicar? Parece recursivo pero no lo veo. ¿Está "getReqursiveItems" dentro de getItems()? – Josiah

+1

@Josiah no estoy seguro de cuál fue mi idea original aquí ... pero edité la respuesta para mostrar un posible uso. –

+2

esto no parece ser recursivo en absoluto, sino que devuelve todos los * nietos * del '$ id original – KnightHawk

Cuestiones relacionadas