Cómo se usan los callbacks en PHP

Hand holding phone coming out from laptop. Contact us flat illustration. Eps8

Este es uno de mis temas preferidos cuando a PHP se refiere.

Debo confesar que lo descubrí bastante tarde, pero fue prácticamente amor a primera vista.

Veamos un ejemplo:

Si tengo un array con números ( [ 1, 2, 3, 4, 5 ] ) y quiero obtener sólo los números pares, la forma normal de hacerlo sería algo como:

$pares = [];
foreach ( $numeros as $numero ) {
   if ( $numero % 2 == 0 ) {
       $pares[] = $numero;
   }
}

Levantemos un poco el nivel de abstracción:

function esPar( $numero )
{
    return $numero % 2 == 0;
}

$pares = [];
foreach ( $numeros as $numero ) {
   if ( esPar( $numero ) ) {
       $pares[] = $numero;
   }
}

Hasta acá la versión clásica.

Ahora, si mirás nuevamente, podés ver que se está llamando a la función esPar() sobre cada uno de los elementos del array $numeros y nos estamos quedando sólo con aquellos que lo son, o, dicho de otro modo, estamos dejando afuera aquellos elementos que no son pares. A esta operación se la conoce como filtro.

Ahora bien, es claro que esPar no es el único criterio por el que podríamos querer filtrar un array.

Si tomamos un ejemplo donde sólo queremos quedarnos con los elementos mayores que tres:

function esMayor3( $numero )
{
    return $numero > 3;
}

$mayores = [];

foreach ( $numeros as $numero ) {
   if ( esMayor3( $numero ) ) {
       $mayores[] = $numero;
   }
}

La estructura de estos dos scripts es muy similar:

  • Se parte de un array
  • Se aplica una función booleana a cada elemento
  • Se retornan sólo los elementos para los cuales la función evalúa en true

Notá que la única diferencia entre los dos scripts es cuál es la condición que determina si el elemento queda adentro del array de resultado o no

Y acá es donde aparece este genial concepto tomado de la programación funcional: la posibilidad de que las funciones puedan ser argumentos de otras funciones.

Si nunca viste este concepto antes, te sugiero que te tomes un par de segundos para digerir lo que acabás de leer.

¿Ya está? Ok, sigamos.

Lo que estoy diciendo es que podrías hacer una función genérica que tome las partes en común de ambas situaciones y reciba como parámetro el criterio de filtro que se debe usar.

Se vería algo como:

function filtrar( array $array, $f )
{
   $res = [];

   foreach ( $array as $elemento ) {
      if ( $f( $elemento ) ) {
         $res[] = $elemento;
      }
   }

   return $res;
}

Notá como $f es a la vez una variable y una función.

A mi esto me recuerda a la escena de Matrix donde el chico monje dobla la cuchara (Si no viste la peli no tiene mucho sentido el comentario, pero si la viste seguro entenderás de lo que hablo)

Antes de seguir te cuento (por si no lo adivinaste aún) que esta función ya existe en PHP: array_filter.

La tomé como ejemplo (existen muchas funciones nativas que usan callbacks) porque me parece de lo más claro para explicar el concepto para quien nunca lo vio, pero las posibilidades son realmente muchas.

La pregunta que puede surgirte es: ¿por qué no puedo seguir escribiendo esto como lo hacía hasta ahora? ¿Qué me aporta conocer los callbacks?

La respuesta es que sí, no hay nada que puedas lograr (desde el punto de vista de funcionalidad) que no pudieras lograr sin usar callbacks.

La segunda pregunta es más interesante. Lo que te aporta usar este mecanismo es lo mismo que cualquier otro mecanismo de abstracción (como las funciones con parámetros por ejemplo) es la posibilidad de lograr el mismo resultado con menor esfuerzo (En este caso, escribiendo menos código, ya que tal vez te exija pensar un poquito más que de la otra forma).

Un buen programador siempre está ávido de nuevas formas de conseguir esto.

Menos código implica menos probabilidades de dejar errores molestos e indetectables, es decir, menos fines de semana y noches sin dormir arreglando el sistema.

¿Qué usos interesantes le ves a este mecanismo?

mchojrin

Por mchojrin

Ayudo a desarrolladores PHP a acceder mercados y clientes más sofisticados y exigentes