Los generadores en PHP, permiten mostrar una secuencia de valores uno a uno sin necesidad de almacenarlos en la memoria.
Nos conviene utilizarlos cuando queremos generar una gran cantidad o conjunto de datos, sin necesidad de cargar toda la información en la memoria al mismo tiempo.
Por eso son una manera eficiente de mostrar una secuencia de valores.
Un generador produce (o genera) un valor uno a uno, en lugar de crear una lista completa de valores de antemano.
Básicamente es una manera eficiente de mostrar valores uno a uno.
Por ejemplo:
<?php function generadorNumeros() { for ($i = 1; $i <= 5; $i++) { yield $i; // Devuelve el número actual uno a uno } } foreach (generadorNumeros() as $numero) { echo $numero . " "; } ?>
En el código anterior, se generan números del 1 al 5, uno a uno y, el bucle foreach nos permite recorrerlos a medida que se generan, ahorrando así memoria ya que, como dije al principio, no los almacena todos en la memoria.
La creación de un generador se hace con la palabra reservada “yield” dentro de la función. De esta manera indicamos que vamos a crear un generador.
Yield no retorna un valor de inmediato, sino que produce valores uno a uno en el momento que se necesiten, es decir, “yield” devuelve valores cada vez que se llama a la función. Cada vez que el bucle solicita un nuevo valor, el generador se reanuda y se produce el siguiente número, y así sucesivamente.
Ahora te puedes preguntar, ¿Qué uso? ¿función normal? ¿o generadora?
Función normal y/o “función generadora”:
Bueno, ten en cuenta que en una función normal donde queremos generar una lista de números, supongamos de 1 a 1.000.000, primero se creará la lista de números completa en la memoria.
En una “función generadora”, los números se generan uno a uno, sobre la marcha.
¿Qué implica todo esto? Eficiencia. En términos generales o en eficiencia de memoria, la función generadora es “más rápida”. Así que… todo depende del contexto.
En el siguiente código puedes comprobar el tiempo de ejecución de cada función y quién es «la ganadora».
// Función normal function generarNumerosNormales() { $numeros = []; for ($i = 1; $i <= 1000000; $i++) { $numeros[] = $i; } return $numeros; } // Función generadora function generarNumerosGenerador() { for ($i = 1; $i <= 1000000; $i++) { yield $i; } } // Medir el tiempo de ejecución de la función normal $inicio = microtime(true); generarNumerosNormales(); $fin = microtime(true); echo "Tiempo de ejecución de la función normal: " . ($fin - $inicio) . " segundos <br>"; // Medir el tiempo de ejecución de la función generadora $inicio = microtime(true); generarNumerosGenerador(); $fin = microtime(true); echo "Tiempo de ejecución de la función generadora: " . ($fin - $inicio) . " segundos";