La version PHP 8.0 trajo un paquete de mejoras de sintaxis que redefinieron el estilo del lenguaje. Esta leccion agrupa cinco de las mas utilizadas en el dia a dia: la expresion match, el operador nullsafe, los argumentos con nombre, la promocion de propiedades en el constructor y la sintaxis first-class callable. Todas se complementan entre si y suelen aparecer juntas en codigo moderno.
La expresion match
La expresion match sustituye al viejo switch cuando lo que quieres es obtener un valor a partir de una entrada. A diferencia de switch, match es una expresion, no una sentencia, por lo que devuelve un valor, y la comparacion se realiza de forma estricta con ===.
<?php
$codigo = 404;
$mensaje = match ($codigo) {
200, 201, 204 => "Operacion correcta",
301, 302 => "Redireccion",
400, 404 => "Solicitud incorrecta",
500, 502 => "Error del servidor",
default => "Codigo desconocido",
};
echo $mensaje;
La coma permite agrupar varios patrones en el mismo brazo sin break ni caida implicita. Si el valor no coincide con ninguno y no hay default, PHP lanza UnhandledMatchError. Ese fallo explicito es deseable: obliga a tratar el caso faltante en lugar de dejar que el flujo siga silenciosamente.
El brazo de match admite cualquier expresion, no solo constantes. Esto permite construir arboles de decision expresivos sin apilar ternarios.
<?php
$descuento = match (true) {
$total > 1000 => 0.20,
$total > 500 => 0.10,
$total > 100 => 0.05,
default => 0.0,
};
El patron match (true) con condiciones booleanas a la derecha es habitual para reglas de negocio ordenadas por prioridad.
La comparacion estricta de
matchevita el clasico error delswitchdonde una cadena y un numero se consideraban iguales. Enmatch, "0" y 0 no coinciden.
Operador nullsafe
El operador ?-> permite encadenar llamadas a metodos o accesos a propiedades sin preocuparse de que alguno de los eslabones sea null. Si lo es, la expresion completa devuelve null sin error.
<?php
final class Direccion
{
public function __construct(public readonly string $ciudad) {}
}
final class Usuario
{
public function __construct(public readonly ?Direccion $direccion) {}
}
$usuario = new Usuario(null);
$ciudad = $usuario->direccion?->ciudad; // null, sin error
Antes de ?-> habia que escribir comprobaciones anidadas o usar el operador ternario repetidas veces. Con nullsafe la intencion queda clara en una sola linea.
El operador encadena, de forma que si cualquier paso intermedio es null la evaluacion se detiene en ese punto.
<?php
$codigoPostal = $pedido?->cliente?->direccion?->codigoPostal ?? "00000";
El operador ?? complementa a ?-> cuando quieres un valor por defecto. Juntos cubren la gran mayoria de patrones que antes requerian isset() repetido.
Named arguments
Los named arguments permiten pasar parametros a funciones y constructores usando el nombre del parametro en lugar de su posicion. Esto mejora la legibilidad, especialmente con funciones que aceptan varios booleanos o valores opcionales.
<?php
function crearUsuario(
string $email,
string $nombre,
bool $activo = true,
bool $recibirNewsletter = false,
?string $telefono = null,
): array {
return [
"email" => $email,
"nombre" => $nombre,
"activo" => $activo,
"recibirNewsletter" => $recibirNewsletter,
"telefono" => $telefono,
];
}
$u = crearUsuario(
email: "alicia@example.com",
nombre: "Alicia",
recibirNewsletter: true,
);
Al invocar con nombres, es posible saltarse los parametros opcionales intermedios y quedarse solo con los que interesan. El codigo gana intencion: quien lee la llamada ya no tiene que recordar si el cuarto argumento posicional era activo o recibirNewsletter.
Los named arguments tambien evitan errores al actualizar firmas. Si alguien reordena los parametros opcionales y todos los clientes usan nombres, nada se rompe.
Constructor property promotion
La promocion de propiedades en el constructor reduce el boilerplate tipico de clases con muchos campos. Cada parametro del constructor que lleva un modificador de visibilidad se convierte en una propiedad de la clase y se asigna automaticamente.
<?php
final class Producto
{
public function __construct(
public readonly string $sku,
public readonly string $nombre,
public readonly float $precio,
public readonly int $stock = 0,
) {}
}
$p = new Producto(sku: "ABC-1", nombre: "Lampara", precio: 29.99);
La combinacion de promocion con readonly y named arguments produce el patron moderno para DTOs y value objects: una clase compacta que se instancia con nombres explicitos y cuyas propiedades son inmutables tras la construccion.
La promocion convive con codigo manual. Puedes promover unos parametros y declarar otros a mano si el constructor necesita realizar calculos o validaciones adicionales.
First-class callable syntax
PHP siempre ha permitido pasar funciones como argumentos, pero la sintaxis tradicional usaba cadenas, arrays con nombre de metodo o cierres. PHP 8.1 introduce la sintaxis funcion(...) para obtener un Closure de cualquier funcion o metodo de forma uniforme.
<?php
$mayusculas = strtoupper(...);
echo $mayusculas("hola"); // "HOLA"
$numeros = [1, 2, 3, 4];
$pares = array_filter($numeros, fn ($n) => $n % 2 === 0);
Para metodos de instancia y de clase se usa la misma sintaxis.
<?php
final class Calculadora
{
public function sumar(int $a, int $b): int
{
return $a + $b;
}
}
$c = new Calculadora();
$op = $c->sumar(...);
echo $op(2, 3); // 5
El resultado es un objeto Closure real, con todas las ventajas que eso implica: se puede pasar a funciones de orden superior, se puede vincular a otro objeto con bindTo() y se beneficia del analisis estatico.
Esta sintaxis unifica la forma de referenciar cualquier callable, desplazando las viejas cadenas y arrays que requerian comprobar is_callable() sin ofrecer seguridad de tipos.
El diagrama resume como interactuan estos cinco elementos en una llamada moderna.
flowchart LR
A[Llamada moderna PHP] --> B[Named arguments]
A --> C[Match expression]
A --> D[Nullsafe]
A --> E[First-class callable]
A --> F[Constructor property promotion]
F --> G[Propiedades readonly]
C --> H[Comparacion estricta]
D --> I[Null-friendly access]
Un ejemplo integrador
Estas piezas suelen aparecer juntas en codigo real. El siguiente ejemplo combina match, nullsafe, named arguments, promocion de propiedades y first-class callable para definir un pequeno router de eventos.
<?php
enum TipoEvento: string
{
case Creacion = "CREATED";
case Actualizacion = "UPDATED";
case Borrado = "DELETED";
}
final class Evento
{
public function __construct(
public readonly TipoEvento $tipo,
public readonly ?string $entidad = null,
) {}
}
$manejadores = [
TipoEvento::Creacion->value => fn (Evento $e) => "crear " . ($e->entidad ?? "desconocido"),
TipoEvento::Borrado->value => fn (Evento $e) => "borrar " . ($e->entidad ?? "desconocido"),
];
$evento = new Evento(tipo: TipoEvento::Creacion, entidad: "usuario");
$resultado = match (true) {
isset($manejadores[$evento->tipo->value]) => $manejadores[$evento->tipo->value]($evento),
default => "sin manejador",
};
echo $resultado; // "crear usuario"
En menos de treinta lineas aparecen enums backed, match estricto, nullsafe implicito via ??, named arguments en el constructor y funciones como valores. Es el estilo que caracteriza al PHP moderno escrito en proyectos profesionales.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, PHP es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de PHP
Explora más contenido relacionado con PHP y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Aplicar match expressions, nullsafe, named arguments, constructor property promotion y first-class callable syntax para escribir codigo PHP moderno mas corto y seguro.