Curso de PHP

Funciones anónimas en PHP: closures y arrow functions

Por Víctor Peña · Publicado el

Funciones anónimas en PHP

Hola, ¿cómo están? Continuando con el curso de PHP, hoy veremos las funciones anónimas. Si las funciones normales tienen nombre y se declaran una vez, estas se crean sobre la marcha justo donde se necesitan.

¡Empecemos!

Qué es una función anónima

Una función anónima es una función sin nombre que se puede guardar en una variable o pasar como argumento a otra función.

<?php
$saludar = function ($nombre) {
    return "Hola, $nombre";
};

echo $saludar("Víctor");   // Hola, Víctor

Fíjate en el punto y coma del final: como la estamos asignando a una variable, es una instrucción y necesita cerrarse.

También se las llama closures, y verás ambos nombres usados indistintamente.

Para qué sirven realmente

La pregunta razonable al verlas por primera vez es: si puedo declarar una función normal, ¿para qué quiero una sin nombre?

La respuesta es que muchas funciones de PHP esperan recibir una función como argumento, para aplicarla a cada elemento de un array. Declarar una función con nombre solo para pasarla una vez sería ruido.

<?php
$numeros = [1, 2, 3, 4, 5];

$dobles = array_map(function ($n) {
    return $n * 2;
}, $numeros);

print_r($dobles);   // [2, 4, 6, 8, 10]

Capturar variables con use

Una función anónima no ve las variables de fuera, igual que una función normal. Para acceder a ellas se usa use:

<?php
$iva = 0.13;

$calcular = function ($precio) use ($iva) {
    return $precio * (1 + $iva);
};

echo $calcular(100);   // 113

Sin ese use ($iva), la variable no existiría dentro de la función.

Un detalle importante: use captura una copia del valor en el momento de crear la función, no una referencia viva:

<?php
$mensaje = "Hola";

$mostrar = function () use ($mensaje) {
    echo $mensaje;
};

$mensaje = "Adiós";
$mostrar();   // imprime "Hola", no "Adiós"

Si necesitas que refleje el cambio, captura por referencia con use (&$mensaje).

Arrow functions

Desde PHP 7.4 existe una sintaxis abreviada muy cómoda:

<?php
$dobles = array_map(fn($n) => $n * 2, $numeros);

Compáralo con la versión larga: pasó de cuatro líneas a una.

Las arrow functions tienen dos características propias:

  1. Solo admiten una expresión, que se devuelve automáticamente. No hay llaves ni return.
  2. Capturan las variables del exterior de forma automática, sin necesidad de use.
<?php
$iva = 0.13;

$calcular = fn($precio) => $precio * (1 + $iva);   // sin use

echo $calcular(100);   // 113

Cuándo usar cada una: arrow function si cabe en una línea, closure con llaves si necesitas varias instrucciones.

Las funciones de array que más vas a usar

Aquí es donde las funciones anónimas cobran todo su sentido.

array_map: transformar cada elemento

<?php
$precios = [100, 250, 80];

$conIva = array_map(fn($p) => round($p * 1.13, 2), $precios);
print_r($conIva);   // [113, 282.5, 90.4]

Devuelve un array del mismo tamaño, con cada elemento transformado.

array_filter: quedarse con algunos

<?php
$numeros = [1, 2, 3, 4, 5, 6, 7, 8];

$pares = array_filter($numeros, fn($n) => $n % 2 === 0);
print_r($pares);   // [2, 4, 6, 8]

Devuelve solo los elementos donde la función da verdadero. Conserva las claves originales, así que si necesitas reindexar, envuélvelo en array_values().

array_reduce: reducir a un solo valor

<?php
$precios = [100, 250, 80];

$total = array_reduce($precios, fn($acumulado, $p) => $acumulado + $p, 0);
echo $total;   // 430

El tercer argumento es el valor inicial. Sirve para sumar, concatenar o construir cualquier cosa a partir de una lista.

usort: ordenar con tu propio criterio

<?php
$productos = [
    ["nombre" => "Monitor", "precio" => 850],
    ["nombre" => "Teclado", "precio" => 120],
    ["nombre" => "Mouse",   "precio" => 60],
];

usort($productos, fn($a, $b) => $a["precio"] <=> $b["precio"]);

Aquí aparece el operador nave espacial <=> que vimos en la lección de comparación: devuelve -1, 0 o 1, que es exactamente lo que usort necesita. Para ordenar de mayor a menor, invierte los operandos.

Un ejemplo práctico

Procesemos una lista de productos combinando varias:

<?php
$productos = [
    ["nombre" => "Monitor", "precio" => 850, "stock" => 3],
    ["nombre" => "Teclado", "precio" => 120, "stock" => 0],
    ["nombre" => "Mouse",   "precio" => 60,  "stock" => 12],
    ["nombre" => "Webcam",  "precio" => 300, "stock" => 5],
];

// 1. Solo los que tienen stock
$disponibles = array_filter($productos, fn($p) => $p["stock"] > 0);

// 2. Ordenados por precio
usort($disponibles, fn($a, $b) => $a["precio"] <=> $b["precio"]);

// 3. El valor total del inventario
$valorTotal = array_reduce(
    $disponibles,
    fn($total, $p) => $total + ($p["precio"] * $p["stock"]),
    0
);

foreach ($disponibles as $p) {
    echo $p["nombre"] . ": " . $p["precio"] . "\n";
}

echo "Valor del inventario: " . $valorTotal;

Escrito con bucles foreach y condicionales funcionaría igual, pero ocuparía el triple y se leería peor.

Funciones que devuelven funciones

Una closure puede devolver otra closure. Suena raro, pero es muy útil:

<?php
function crearMultiplicador(int $factor): callable
{
    return fn($numero) => $numero * $factor;
}

$duplicar = crearMultiplicador(2);
$triplicar = crearMultiplicador(3);

echo $duplicar(10);    // 20
echo $triplicar(10);   // 30

crearMultiplicador fabrica funciones a medida. El tipo callable indica que se devuelve algo ejecutable.

Errores comunes

  • Olvidar el punto y coma al final de la asignación de una closure.
  • Olvidar use y encontrarte con una variable indefinida dentro.
  • Esperar que use capture cambios posteriores. Captura el valor del momento.
  • Usar llaves en una arrow function. No las admite: si necesitas varias líneas, usa la sintaxis larga.
  • Olvidar array_values() tras un array_filter, cuando el resultado va a recorrerse por índice numérico.

Para cerrar

Las funciones anónimas son la puerta de entrada a un estilo de escritura más declarativo: en vez de explicar paso a paso cómo recorrer una lista, dices qué quieres obtener de ella.

Empieza usándolas con array_map, array_filter y usort. Son las tres que aparecen constantemente en cualquier proyecto real.

En la siguiente lección empezamos el bloque de programación orientada a objetos.

Saludos y éxitos.

Norvic Software

Desarrollamos el software que tu empresa necesita

Somos una fábrica de software en Bolivia. Construimos sistemas a medida y aplicaciones móviles, y llevamos Inteligencia Artificial a las empresas que ya tienen un sistema funcionando.

Solicitar cotizaciónVer todos los servicios

Cotización sin costo · Respuesta directa por WhatsApp