libro / blog / funciones-php-tipos-closures

// funciones

Funciones en PHP: tipos, argumentos con nombre, closures y arrow functions

Gustavo Arias9 min de lectura

TL;DR Declara siempre los tipos de los parámetros y del retorno: documentan la función y PHP los hace cumplir. Usa argumentos con nombre cuando una llamada tiene varios parámetros opcionales, y arrow functions con array_map, array_filter y usort para transformar datos en una línea.

Las funciones son la herramienta para no repetirte: escribes la lógica una vez, le pones un nombre y la reutilizas. PHP ha incorporado en sus últimas versiones tipos estrictos, argumentos con nombre y arrow functions, que hacen las funciones mucho más expresivas. En el libro PHP desde cero hasta experto las funciones tienen un capítulo propio; aquí tienes lo que necesitas para escribirlas como un profesional.

Anatomía de una función

<?php
declare(strict_types=1);

//       nombre     parámetros con tipo            tipo de retorno
function calcularIva(float $precio, float $tasa = 0.21): float
{
    return round($precio * $tasa, 2);
}

echo calcularIva(1000);        // 210
echo calcularIva(1000, 0.105); // 105

Una buena función hace una sola cosa, tiene un nombre que empieza con un verbo (calcular, validar, enviar) y devuelve un resultado en lugar de imprimirlo, para poder usarlo donde haga falta.

Tipos de parámetros y de retorno

<?php
declare(strict_types=1);

// ?string: puede ser string o null
function saludar(?string $nombre): string
{
    return 'Hola, ' . ($nombre ?? 'invitado');
}

// int|float: tipo unión (PHP 8)
function doble(int|float $n): int|float
{
    return $n * 2;
}

// void: no devuelve nada
function registrar(string $mensaje): void
{
    error_log($mensaje);
}

// array con su forma documentada en un comentario
/** @return array{ok: bool, errores: string[]} */
function validarEmail(string $email): array
{
    $ok = filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    return ['ok' => $ok, 'errores' => $ok ? [] : ['Email no válido']];
}

Los tipos son documentación que PHP verifica. Con strict_types activado (lo explicamos en tipos de datos y operadores), un tipo incorrecto falla en el momento de la llamada, no más tarde con un resultado raro.

Valores por defecto y argumentos con nombre

Cuando una función tiene varios parámetros opcionales, los argumentos con nombre (PHP 8) evitan pasar valores “de relleno” y hacen la llamada autoexplicativa:

<?php
function formatearPrecio(
    float $monto,
    string $moneda = '$',
    int $decimales = 2,
    string $separadorMiles = '.',
): string {
    return $moneda . number_format($monto, $decimales, ',', $separadorMiles);
}

// Sin nombres: ¿qué significa cada argumento?
echo formatearPrecio(1500, '$', 0, '.');

// Con nombres: solo lo que cambias, en cualquier orden
echo formatearPrecio(1500, decimales: 0);   // $1.500

// También funciona con funciones nativas
echo htmlspecialchars($texto, double_encode: false);

Closures y arrow functions

Una función anónima (closure) es una función sin nombre que puedes guardar en una variable o pasar como argumento. Las arrow functions (fn, PHP 7.4) son su versión corta para expresiones de una línea.

<?php
$iva = 0.21;

// Closure clásica: hay que importar las variables externas con use
$conIva = function (float $precio) use ($iva): float {
    return $precio * (1 + $iva);
};

// Arrow function: captura las variables externas automáticamente
$conIvaCorta = fn(float $precio): float => $precio * (1 + $iva);

echo $conIva(100);       // 121
echo $conIvaCorta(100);  // 121
Diferencia clave: una arrow function solo puede contener una expresión. Si necesitas varias líneas, usa function () use (...) { }.

Funciones + arrays: map, filter y usort

Aquí es donde las arrow functions brillan: transformar listas sin escribir bucles.

<?php
$productos = [
    ['nombre' => 'Teclado', 'precio' => 45000, 'stock' => 10],
    ['nombre' => 'Mouse',   'precio' => 18000, 'stock' => 0],
    ['nombre' => 'Monitor', 'precio' => 210000, 'stock' => 4],
];

// Filtrar: solo los que tienen stock
$disponibles = array_filter($productos, fn($p) => $p['stock'] > 0);

// Transformar: solo los nombres
$nombres = array_map(fn($p) => $p['nombre'], $disponibles);

// Ordenar por precio, de mayor a menor
usort($productos, fn($a, $b) => $b['precio'] <=> $a['precio']);

// Sumar el valor del inventario
$total = array_sum(array_map(fn($p) => $p['precio'] * $p['stock'], $productos));

print_r(array_values($nombres)); // [Teclado, Monitor]
echo $total;                     // 1290000

Ojo: array_filter conserva las claves originales. Usa array_values() si necesitas un array con índices consecutivos, por ejemplo antes de convertirlo a JSON.

Buenas prácticas

Referencia: funciones y arrow functions en el manual de PHP.

Código reutilizable desde el primer proyecto

El libro PHP desde cero hasta experto dedica un capítulo a las funciones, la base para organizar el código de los proyectos prácticos del libro.

Comprar en Amazon