Lección 23 de 75 8 min de lectura

Argumentos Nombrados

Los argumentos nombrados (named arguments) son una característica de PHP 8 que permite pasar argumentos especificando el nombre del parámetro. Esto mejora la legibilidad y permite saltar parámetros opcionales.

Sintaxis básica

En lugar de pasar argumentos por posición, puedes usar el nombre del parámetro seguido de dos puntos:

PHP
<?php

declare(strict_types=1);

function crearUsuario(string $nombre, string $email, int $edad): array
{
    return [
        'nombre' => $nombre,
        'email' => $email,
        'edad' => $edad,
    ];
}

// Argumentos posicionales (tradicional)
$usuario1 = crearUsuario('Ana', 'ana@example.com', 25);

// Argumentos nombrados (PHP 8+)
$usuario2 = crearUsuario(
    nombre: 'Ana',
    email: 'ana@example.com',
    edad: 25
);

// El resultado es idéntico
print_r($usuario1);
print_r($usuario2);

Cambiar el orden de los argumentos

Con argumentos nombrados, el orden no importa. PHP los asocia por nombre:

PHP
<?php

declare(strict_types=1);

function enviarEmail(string $para, string $asunto, string $cuerpo): void
{
    echo "Para: $para\n";
    echo "Asunto: $asunto\n";
    echo "Cuerpo: $cuerpo\n";
}

// Orden diferente al de la definición
enviarEmail(
    cuerpo: 'Hola, ¿cómo estás?',
    para: 'ana@example.com',
    asunto: 'Saludos'
);

// Funciona igual que:
enviarEmail(
    para: 'ana@example.com',
    asunto: 'Saludos',
    cuerpo: 'Hola, ¿cómo estás?'
);

Saltar parámetros opcionales

Esta es una de las mayores ventajas: puedes saltar parámetros que tienen valores por defecto:

PHP
<?php

declare(strict_types=1);

function crearConexion(
    string $host = 'localhost',
    int $puerto = 3306,
    string $usuario = 'root',
    string $password = '',
    string $baseDatos = 'test',
    string $charset = 'utf8mb4'
): array {
    return [
        'host' => $host,
        'puerto' => $puerto,
        'usuario' => $usuario,
        'password' => $password,
        'baseDatos' => $baseDatos,
        'charset' => $charset,
    ];
}

// Sin argumentos nombrados: hay que pasar todos los anteriores
$conn1 = crearConexion('localhost', 3306, 'root', '', 'mi_app');

// Con argumentos nombrados: solo lo que necesitas cambiar
$conn2 = crearConexion(baseDatos: 'mi_app');

// Cambiar solo el charset
$conn3 = crearConexion(charset: 'latin1');

// Cambiar host y base de datos, mantener el resto
$conn4 = crearConexion(
    host: '192.168.1.100',
    baseDatos: 'produccion'
);

print_r($conn2);
/*
[
    'host' => 'localhost',
    'puerto' => 3306,
    'usuario' => 'root',
    'password' => '',
    'baseDatos' => 'mi_app',
    'charset' => 'utf8mb4',
]
*/
Código más limpio

Los argumentos nombrados eliminan la necesidad de pasar valores por defecto solo para llegar a un parámetro posterior.

Combinar argumentos posicionales y nombrados

Puedes mezclar ambos estilos, pero los posicionales deben ir primero:

PHP
<?php

declare(strict_types=1);

function formatearFecha(
    string $fecha,
    string $formato = 'Y-m-d',
    string $zonaHoraria = 'Europe/Madrid'
): string {
    $dt = date_create($fecha, timezone_open($zonaHoraria));
    return date_format($dt, $formato);
}

// Posicional + nombrado
echo formatearFecha('2024-01-15', formato: 'd/m/Y');
// 15/01/2024

// El primer argumento es posicional, el resto nombrado
echo formatearFecha('2024-01-15', zonaHoraria: 'America/New_York');

// ❌ Error: argumentos posicionales después de nombrados
// formatearFecha(formato: 'd/m/Y', '2024-01-15');

Documentación automática

Los argumentos nombrados hacen el código más autodocumentado, especialmente con valores booleanos o números:

PHP
<?php

declare(strict_types=1);

function copiarArchivo(
    string $origen,
    string $destino,
    bool $sobrescribir = false,
    bool $crearDirectorio = true,
    int $permisos = 0644
): bool {
    // Implementación...
    echo "Copiando $origen a $destino\n";
    echo 'Sobrescribir: ' . ($sobrescribir ? 'sí' : 'no') . "\n";
    echo 'Crear directorio: ' . ($crearDirectorio ? 'sí' : 'no') . "\n";
    return true;
}

// ❌ Sin argumentos nombrados: ¿qué significa true, true, 0755?
copiarArchivo('/tmp/a.txt', '/var/b.txt', true, true, 0755);

// ✅ Con argumentos nombrados: claro y autodocumentado
copiarArchivo(
    origen: '/tmp/a.txt',
    destino: '/var/b.txt',
    sobrescribir: true,
    crearDirectorio: true,
    permisos: 0755
);

// Aún mejor: solo los parámetros que cambian
copiarArchivo(
    origen: '/tmp/a.txt',
    destino: '/var/b.txt',
    sobrescribir: true
);

Con funciones nativas de PHP

Los argumentos nombrados también funcionan con funciones nativas de PHP:

PHP
<?php

declare(strict_types=1);

// str_replace con argumentos nombrados
$texto = str_replace(
    search: 'mundo',
    replace: 'PHP',
    subject: 'Hola mundo'
);
echo $texto; // Hola PHP

// array_fill
$array = array_fill(
    start_index: 0,
    count: 5,
    value: 'x'
);
print_r($array); // ['x', 'x', 'x', 'x', 'x']

// setcookie con argumentos nombrados (muy útil)
setcookie(
    name: 'usuario',
    value: 'ana123',
    expires_or_options: time() + 3600,
    path: '/',
    secure: true,
    httponly: true
);

// htmlspecialchars saltando el segundo parámetro
$html = htmlspecialchars(
    string: '<script>alert("hola")</script>',
    double_encode: false
);

// json_encode con opciones específicas
$json = json_encode(
    value: ['nombre' => 'Ana', 'ciudad' => 'España'],
    flags: JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
);
echo $json;

Ejemplo práctico

PHP
<?php

declare(strict_types=1);

// Sistema de notificaciones con muchas opciones

function crearNotificacion(
    string $mensaje,
    string $titulo = 'Notificación',
    string $tipo = 'info',
    bool $persistente = false,
    int $duracion = 5000,
    ?string $icono = null,
    ?string $enlace = null,
    bool $sonido = true,
    string $posicion = 'top-right'
): array {
    $iconoFinal = $icono ?? match ($tipo) {
        'success' => '✓',
        'error' => '✗',
        'warning' => '⚠',
        default => 'ℹ',
    };

    return [
        'mensaje' => $mensaje,
        'titulo' => $titulo,
        'tipo' => $tipo,
        'persistente' => $persistente,
        'duracion' => $duracion,
        'icono' => $iconoFinal,
        'enlace' => $enlace,
        'sonido' => $sonido,
        'posicion' => $posicion,
    ];
}

// Notificación simple
$n1 = crearNotificacion(mensaje: 'Operación completada');

// Notificación de error persistente
$n2 = crearNotificacion(
    mensaje: 'Error al guardar',
    tipo: 'error',
    persistente: true,
    sonido: false
);

// Notificación con enlace
$n3 = crearNotificacion(
    mensaje: 'Nuevo mensaje recibido',
    titulo: 'Bandeja de entrada',
    enlace: '/mensajes/123',
    posicion: 'bottom-left'
);

// Notificación de éxito corta
$n4 = crearNotificacion(
    mensaje: 'Guardado',
    tipo: 'success',
    duracion: 2000
);

print_r($n2);
/*
[
    'mensaje' => 'Error al guardar',
    'titulo' => 'Notificación',
    'tipo' => 'error',
    'persistente' => true,
    'duracion' => 5000,
    'icono' => '✗',
    'enlace' => null,
    'sonido' => false,
    'posicion' => 'top-right',
]
*/
PHP
<?php

declare(strict_types=1);

// Función de búsqueda con muchos filtros opcionales

function buscarProductos(
    ?string $nombre = null,
    ?float $precioMinimo = null,
    ?float $precioMaximo = null,
    ?string $categoria = null,
    bool $soloDisponibles = false,
    string $ordenarPor = 'nombre',
    string $direccion = 'ASC',
    int $limite = 20,
    int $pagina = 1
): array {
    // Simular búsqueda - en producción sería una consulta a BD
    $filtros = [];

    if ($nombre !== null) {
        $filtros[] = "nombre LIKE '%$nombre%'";
    }
    if ($precioMinimo !== null) {
        $filtros[] = "precio >= $precioMinimo";
    }
    if ($precioMaximo !== null) {
        $filtros[] = "precio <= $precioMaximo";
    }
    if ($categoria !== null) {
        $filtros[] = "categoria = '$categoria'";
    }
    if ($soloDisponibles) {
        $filtros[] = 'stock > 0';
    }

    return [
        'filtros' => $filtros,
        'orden' => "$ordenarPor $direccion",
        'limite' => $limite,
        'offset' => ($pagina - 1) * $limite,
    ];
}

// Buscar solo por categoría
$resultado1 = buscarProductos(categoria: 'electrónica');

// Buscar con rango de precio
$resultado2 = buscarProductos(
    precioMinimo: 10.0,
    precioMaximo: 50.0,
    soloDisponibles: true
);

// Buscar con paginación específica
$resultado3 = buscarProductos(
    nombre: 'camiseta',
    ordenarPor: 'precio',
    direccion: 'DESC',
    pagina: 3
);

print_r($resultado2);
/*
[
    'filtros' => ['precio >= 10', 'precio <= 50', 'stock > 0'],
    'orden' => 'nombre ASC',
    'limite' => 20,
    'offset' => 0,
]
*/
Cuidado al renombrar parámetros

Si cambias el nombre de un parámetro en una función, romperás cualquier código que use ese nombre como argumento nombrado. Ten esto en cuenta en código que compartas con otros.

Ejercicios

Ejercicio 1: Configuracion con argumentos nombrados

Tienes esta funcion: function crearBoton(string $texto, string $tipo = 'primary', string $tamano = 'medium', bool $deshabilitado = false): string. Llamala creando un boton con texto "Enviar", tamano "large" y deshabilitado, pero manteniendo el tipo por defecto. Usa argumentos nombrados.

Ver solucion
PHP
<?php
declare(strict_types=1);

function crearBoton(
    string $texto,
    string $tipo = 'primary',
    string $tamano = 'medium',
    bool $deshabilitado = false
): string {
    $disabled = $deshabilitado ? ' disabled' : '';
    return "<button class=\"btn btn-$tipo btn-$tamano\"$disabled>$texto</button>";
}

// Usando argumentos nombrados para saltar 'tipo'
$boton = crearBoton(
    texto: 'Enviar',
    tamano: 'large',
    deshabilitado: true
);

echo $boton;
// <button class="btn btn-primary btn-large" disabled>Enviar</button>

Ejercicio 2: Funcion con muchos parametros

Crea una funcion crearEmail con los parametros: destinatario (obligatorio), asunto (por defecto 'Sin asunto'), cuerpo (por defecto ''), cc (por defecto null), adjunto (por defecto null). Retorna un array con la informacion. Llamala enviando solo destinatario y adjunto.

Ver solucion
PHP
<?php
declare(strict_types=1);

function crearEmail(
    string $destinatario,
    string $asunto = 'Sin asunto',
    string $cuerpo = '',
    ?string $cc = null,
    ?string $adjunto = null
): array {
    return [
        'para' => $destinatario,
        'asunto' => $asunto,
        'cuerpo' => $cuerpo,
        'cc' => $cc,
        'adjunto' => $adjunto,
    ];
}

$email = crearEmail(
    destinatario: 'usuario@example.com',
    adjunto: 'documento.pdf'
);

print_r($email);
/*
[
    'para' => 'usuario@example.com',
    'asunto' => 'Sin asunto',
    'cuerpo' => '',
    'cc' => null,
    'adjunto' => 'documento.pdf',
]
*/

Ejercicio 3: Combinar posicionales y nombrados

Usa la funcion nativa str_pad para rellenar el string "42" hasta tener 5 caracteres, rellenando con ceros a la izquierda. Usa argumentos nombrados para el parametro pad_type (valor: STR_PAD_LEFT) y pad_string (valor: '0').

Ver solucion
PHP
<?php
declare(strict_types=1);

$resultado = str_pad(
    '42',
    5,
    pad_string: '0',
    pad_type: STR_PAD_LEFT
);

echo $resultado; // 00042

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales y soporte personalizado.

Descubrir cursos premium