Autor Tema: Ambito de variables en funciones anonimas php  (Leído 1972 veces)

gatoher

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 86
    • Ver Perfil
Ambito de variables en funciones anonimas php
« en: 12 de Diciembre 2022, 12:09 »
Hola a todos!! Estoy viendo las funciones anónimas en php en la documentación oficial. Cuando llego al ejemplo de un carrito  no comprendo como como el método llamadaDeRetorno accede a las variables cantidad y producto pues no se las pasa como un argumento y no están instanciadas en ninguna parte.Solo están declaradas en el método añadir. ¿Podría alguien explicarme como tiene acceso a ellas?

Código: [Seleccionar]
class Carro
{
    const PRECIO_MANTEQUILLA = 1.00;
    const PRECIO_LECHE       = 3.00;
    const PRECIO_HUEVOS      = 6.95;

    protected $productos = array();

    public function añadir($producto, $cantidad)
    {
        $this->productos[$producto] = $cantidad;
    }

    public function obtenerCantidad($producto)
    {
        return isset($this->productos[$producto]) ? $this->productos[$producto] :
               FALSE;
    }

    public function obtenerTotal($impuesto)
    {
        $total = 0.00;

        $llamadaDeRetorno =
            function ($cantidad, $producto) use ($impuesto, &$total)
            {
                $precioUnidad = constant(__CLASS__ . "::PRECIO_" .
                    strtoupper($producto));
                $total += ($precioUnidad * $cantidad) * ($impuesto + 1.0);
            };

        array_walk($this->productos, $llamadaDeRetorno);
        return round($total, 2);
    }
}

$mi_carro = new Carro;

// Añadir algunos artículos al carro
$mi_carro->añadir('mantequilla', 1);
$mi_carro->añadir('leche', 3);
$mi_carro->añadir('huevos', 6);

// Imprimir el total con un impuesto de venta del 5%.
print $mi_carro->obtenerTotal(0.05) . "\n";
// El resultado es 54.29
?>


Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re: Ambito de variables en funciones anonimas php
« Respuesta #1 en: 13 de Diciembre 2022, 11:24 »
Buenas, tal y como lo veo yo se trataría de un caso de asignación de una función a una variable.

Un ejemplo de esto sería lo siguiente:

<?php
$f = 'strlen';
echo $f('Tarde');

Cuando ejecutamos esto la salida que devuelve es: 5

Esto ocurre porque php permite asignar funciones a nombres de variables y luego invocar la función añadiendo los parámetros necesarios entre paréntesis después del nombre de variable.

En el caso que comentas, la variable $llamadaDeRetorno está asignada a una función anónima que recibe como parámetros $cantidad y $producto, por tanto hace uso de estos porque los recibe (o los recibirá en su momento).

No sé si era esto lo que te generaba dudas o si era otra cosa. Salu2

gatoher

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 86
    • Ver Perfil
Re: Ambito de variables en funciones anonimas php
« Respuesta #2 en: 13 de Diciembre 2022, 11:31 »
Hola Ogramar, pero mi duda es que las variables "$producto, $cantidad" nunca le son pasadas como argumento a la función "$llamadaDeRetorno ". No lo termino de ver por eso. A este método se le llama desde esta línea:

Código: [Seleccionar]
array_walk($this->productos, $llamadaDeRetorno);


Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re: Ambito de variables en funciones anonimas php
« Respuesta #3 en: 13 de Diciembre 2022, 12:29 »
Buenas, aquí creo que se entra en otros detalles.

En esta línea: array_walk($this->productos, $llamadaDeRetorno); lo que diría yo que se hace es que se llama a la función array_walk, y a esta se le pasan dos parámetros: un array ($this->productos) y una función ($llamadaDeRetorno).

La función array_walk lo que hace es ejecutar la función usando el índice y valor o key y value de cada elemento del array. Además podrían incluirse otros parámetros en la llamada de array_walk, pero en este caso no lo hace.

En este ejemplo:

Código: [Seleccionar]
<?php
function myfunction($value,$key)
{
echo 
"The key $key has the value $value<br>";
}
$a=array("a"=>"red","b"=>"green","c"=>"blue");
array_walk($a,"myfunction");
?>

Lo que se obtiene es:

The key a has the value red
The key b has the value green
The key c has the value blue

¿Por qué? Porque al pasar un array, se está pasando indirectamente para cada elemento del array un índice o key y un value o valor.

Entonces cuando llamas esto: array_walk($this->productos, $llamadaDeRetorno);

Lo que estás diciendo es que se va a ejecutar la función llamadaDeRetorno para cada uno de los elementos del array, y en cada ejecución llamadaDeRetorno recibe dos parámetros, que son el key y el value de cada elemento del array. El key es el producto, y el value la cantidad. Por tanto la función recibe lo que necesita.

Yo por lo que veo al carro le va añadiendo productos donde el key es el nombre del producto, por ejemplo 'mantequilla' y el value es la cantidad de producto, por ejemplo 1. Así que llamadaDeRetorno está recibiendo el producto (key de cada elemento del array) y la cantidad (value de cada elemento del array).

Tener un array donde los índices son nombres es algo a lo que muchos no estamos acostumbrados, pero php lo permite.

$age = array("Peter"=>"35", "Ben"=>"37", "Joe"=>"43"); es un array asociativo (con índices nombres). También puede escribirse:

$age['Peter'] = "35";
$age['Ben'] = "37";
$age['Joe'] = "43";

Un ejemplo de uso sería:

 <?php
$age = array("Peter"=>"35", "Ben"=>"37", "Joe"=>"43");
echo "Peter is " . $age['Peter'] . " years old.";
?>

Otros lenguajes no permiten esto, pero PHP sí lo permite.

En este caso

$productos['mantequilla'] = "1";
$productos['leche'] = "3";
$productos['huevos'] = "6";

Lo que indica es que en el array productos tienes tres elementos cuyas key son mantequilla, leche y huevos. Y estos elementos del array tienen como value 1, 3 y 6.

A mí particularmente no me gusta mucho este planteamiento, pero bueno, así es como parece que lo han hecho.


gatoher

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 86
    • Ver Perfil
Re: Ambito de variables en funciones anonimas php
« Respuesta #4 en: 14 de Diciembre 2022, 11:23 »
Gracias Ogramar, muy bien explicado de verdad lo he comprendido. El ejemplo no es mio, es de la documentación de PHP oficial:

https://www.php.net/manual/es/functions.anonymous.php

Muchas gracias estaba yo intrigado, voy a seguir leyendo sobre funciones anónimas  y la clase CLOUSORE

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".