Imagina que tenemos una lista de elementos y queremos saber si alguno de ellos es un email válido. La lista podría ser algo así:
$nombres = [
'emailincorrecto@dominio',
'emailbueno@dominio.com',
'Jaime',
'emailincorrectodominio.com',
];
Para solucionar el problema seguramente recurrirías a un foreach:
$emailsValidos = [];
foreach ($nombres as $nombre) {
if (filter_var($nombre, FILTER_VALIDATE_EMAIL)) {
$emailsValidos[] = $nombre;
}
}
Pero tenemos otra opción que muchos programadores no conocen (o no han usado nunca), se trata de la función array_filter. Usando esta función el código quedaría algo así:
$emailsValidos = array_filter($nombres, function ($elemento) {
return filter_var($elemento, FILTER_VALIDATE_EMAIL);
});
Para más información sobre array_filter visita la documentación oficial de PHP.
Esta función tiene como primer parámetro el array con el que queremos trabajar. El segundo parámetro es una función que podemos teclear directamente. A esta función sin nombre, por cierto, se la suele llamar closure.
El resultado de la función es un nuevo array (no modifica el original) que contiene los elementos que cumplan la condición que hayamos impuesto en el closure.
En este caso hemos usado una función anónima (sin nombre) que es la que se encarga de comprobar si el email es válido:
function ($elemento) {
return filter_var($elemento, FILTER_VALIDATE_EMAIL);
}
Si esta función devuelve un valor true el elemento se añade al array final. Si devuelve false el elemento se ignora.
En lugar de usar un closure (o función anónima) podemos usar una función definida previamente:
function esEmail($elemento) {
return filter_var($elemento, FILTER_VALIDATE_EMAIL);
}
Y la usaríamos así:
$emailsValidos = array_filter($nombres, "esEmail");
¿Qué método es mejor?
En versiones “antiguas” de PHP los bucles foreach ganaban por goleada, eran considerablemente más rápidos. Sin embargo desde la versión 7 los tiempos se han igualado mucho.
¿Y por qué es más rápido el foreach? Mi suposición es que se debe que para cada elemento del array la función array_filter tiene que llamar a una función con el coste extra que eso supone.
Pero dada la poca diferencia de velocidad que hay actualmente entre ambas opciones, escoger una u otra es cuestión de gustos.
A mi personalmente me resultaban muy confusas al principio dado que estaba acostumbrado a los bucles foreach. Pero ahora las encuentro más elegantes y fáciles de entender.
En cualquier caso, prefieras la opción que prefieras, es conveniente conocer ambas.