Tema
Condicionales y match
Los programas útiles toman decisiones: "si el usuario es admin, muestra el panel", "si el stock es cero, muestra Agotado". En esta lección dominarás if, else, elseif, switch y la moderna expresión match, además de la sintaxis alternativa ideal para mezclar PHP con HTML.
Concepto
Una condicional es un cruce de caminos: el programa evalúa una pregunta de sí/no y, según la respuesta, sigue un camino u otro. La "pregunta" es cualquier expresión que se pueda convertir en true o false.
if, else, elseif
php
<?php
declare(strict_types=1);
$edad = 16;
if ($edad >= 18) {
echo 'Puedes votar.';
} elseif ($edad >= 16) {
echo 'Pronto podrás votar.';
} else {
echo 'Aún eres menor de edad.';
}- Las condiciones se evalúan de arriba a abajo y sólo se ejecuta el primer bloque verdadero.
elsees opcional y atrapa "todo lo demás".- Puedes escribir
elseifoelse if; usaelseif, es lo convencional.
Condiciones combinadas
php
<?php
$rol = 'editor';
$activo = true;
if ($activo && ($rol === 'admin' || $rol === 'editor')) {
echo 'Puedes editar artículos.';
}
// in_array: forma más limpia de comparar contra varias opciones
if ($activo && in_array($rol, ['admin', 'editor'], true)) { // true = comparación estricta
echo 'Puedes editar artículos.';
}Retorno temprano (guard clauses)
En vez de anidar muchos if, sal en cuanto algo falle. El código queda plano y legible.
php
<?php
function puedeComprar(?array $usuario, int $stock): string
{
if ($usuario === null) {
return 'Inicia sesión para comprar.';
}
if (!$usuario['verificado']) {
return 'Verifica tu correo primero.';
}
if ($stock === 0) {
return 'Producto agotado.';
}
return 'OK';
}
echo puedeComprar(['verificado' => true], 3); // OKCompáralo con la versión anidada (difícil de leer):
php
<?php
// MAL: "código flecha", evítalo
if ($usuario !== null) {
if ($usuario['verificado']) {
if ($stock > 0) {
echo 'OK';
}
}
}Sintaxis alternativa para plantillas
Cuando mezclas PHP con HTML, las llaves { } se pierden entre etiquetas. PHP ofrece una sintaxis con : y endif; mucho más legible:
php
<?php
$usuario = ['nombre' => 'Carla', 'rol' => 'admin'];
$carrito = [];
?>
<nav>
<?php if ($usuario): ?>
<span>Hola, <?= htmlspecialchars($usuario['nombre']) ?></span>
<?php if ($usuario['rol'] === 'admin'): ?>
<a href="/admin">Panel</a>
<?php endif; ?>
<a href="/logout.php">Salir</a>
<?php else: ?>
<a href="/login.php">Iniciar sesión</a>
<?php endif; ?>
</nav>
<?php if (count($carrito) === 0): ?>
<p>Tu carrito está vacío.</p>
<?php elseif (count($carrito) === 1): ?>
<p>Tienes 1 producto.</p>
<?php else: ?>
<p>Tienes <?= count($carrito) ?> productos.</p>
<?php endif; ?>Buena práctica
Usa llaves { } en archivos de lógica pura y la sintaxis if: ... endif; en vistas/plantillas HTML. Es la convención que verás en WordPress y en proyectos PHP clásicos.
switch
Compara una variable contra varios valores. Útil, pero con trampas.
php
<?php
$dia = 'sábado';
switch ($dia) {
case 'sábado':
case 'domingo': // Varios casos comparten código
echo 'Fin de semana';
break; // ¡Sin break, sigue ejecutando el siguiente case!
case 'viernes':
echo 'Casi fin de semana';
break;
default:
echo 'Día laboral';
}Error común
Olvidar break en un switch. La ejecución "cae" al siguiente case (fall-through) y obtienes resultados raros. Además, switch compara con == (flexible): switch (0) coincide con case 'a' en PHP 7. Por eso, en PHP 8 preferimos match.
match (PHP 8+)
match es una expresión: devuelve un valor. Compara con ===, no necesita break y lanza un error si ningún caso coincide (en lugar de fallar en silencio).
php
<?php
declare(strict_types=1);
$estado = 'enviado';
$etiqueta = match ($estado) {
'pendiente' => 'Esperando pago',
'pagado', 'empacado' => 'Preparando tu pedido', // Varios valores separados por coma
'enviado' => 'En camino',
'entregado' => 'Entregado',
default => 'Estado desconocido',
};
echo $etiqueta; // En caminomatch sin default
php
<?php
$metodo = 'bitcoin';
$comision = match ($metodo) {
'tarjeta' => 0.035,
'oxxo' => 0.02,
};
// UnhandledMatchError: Unhandled match case 'bitcoin'Esto es bueno: te avisa que olvidaste un caso, en lugar de seguir con un valor incorrecto.
match (true) para rangos
Para condiciones complejas, compara contra true: gana el primer brazo cuya condición sea verdadera.
php
<?php
$calificacion = 87;
$letra = match (true) {
$calificacion >= 90 => 'A',
$calificacion >= 80 => 'B',
$calificacion >= 70 => 'C',
$calificacion >= 60 => 'D',
default => 'F',
};
echo $letra; // BComparativa
switch | match | |
|---|---|---|
| Comparación | == (flexible) | === (estricta) |
| Devuelve valor | No | Sí |
Necesita break | Sí | No |
| Sin coincidencia | No hace nada | Lanza UnhandledMatchError |
| Varias instrucciones por caso | Sí | No (una expresión por brazo) |
Si en un caso necesitas varias instrucciones, usa if o switch, o llama a una función desde el brazo del match.
Ejemplo completo: calculadora de envío
php
<?php
declare(strict_types=1);
/**
* Calcula el costo de envío según la zona y el peso (kg).
*/
function costoEnvio(string $zona, float $peso, float $totalCompra): float
{
// Envío gratis en compras grandes
if ($totalCompra >= 1500) {
return 0;
}
$base = match ($zona) {
'local' => 60,
'nacional' => 150,
'frontera' => 220,
default => throw new InvalidArgumentException("Zona no válida: $zona"),
};
// Recargo por peso
$recargo = match (true) {
$peso <= 1 => 0,
$peso <= 5 => 50,
$peso <= 20 => 120,
default => 300,
};
return $base + $recargo;
}
echo costoEnvio('nacional', 3.2, 900); // 200
echo '<br>';
echo costoEnvio('local', 0.5, 2000); // 0Observa que en PHP 8 throw también es una expresión y puede ir dentro de un match.
Ejercicios
- Escribe un script que, dado
$mes(1 a 12), muestre la estación del año en el hemisferio norte usandomatch. - Crea una función
tipoTriangulo(float $a, float $b, float $c): stringque devuelva "Equilátero", "Isósceles" o "Escaleno". - Escribe una plantilla HTML con sintaxis alternativa que muestre un aviso verde si
$stock > 10, amarillo si está entre 1 y 10, y rojo "Agotado" si es 0.
Ver solución
php
<?php
declare(strict_types=1);
$mes = 7;
$estacion = match ($mes) {
12, 1, 2 => 'Invierno',
3, 4, 5 => 'Primavera',
6, 7, 8 => 'Verano',
9, 10, 11 => 'Otoño',
default => 'Mes inválido',
};
echo $estacion; // Veranophp
<?php
declare(strict_types=1);
function tipoTriangulo(float $a, float $b, float $c): string
{
return match (true) {
$a === $b && $b === $c => 'Equilátero',
$a === $b || $b === $c || $a === $c => 'Isósceles',
default => 'Escaleno',
};
}
echo tipoTriangulo(3, 3, 3); // Equilátero
echo tipoTriangulo(3, 4, 3); // Isósceles
echo tipoTriangulo(3, 4, 5); // Escalenophp
<?php $stock = 4; ?>
<?php if ($stock > 10): ?>
<p style="color: green">Disponible</p>
<?php elseif ($stock > 0): ?>
<p style="color: orange">¡Últimas <?= $stock ?> piezas!</p>
<?php else: ?>
<p style="color: red">Agotado</p>
<?php endif; ?>Resumen
if / elseif / elseevalúa de arriba a abajo y ejecuta el primer bloque verdadero.- Prefiere retornos tempranos a
ifanidados. - En plantillas usa
if: ... elseif: ... else: ... endif;. switchcompara con==y necesitabreak; úsalo con cuidado.matches estricto, devuelve un valor y avisa si falta un caso: tu opción por defecto en PHP 8.match (true)resuelve rangos y condiciones complejas de forma elegante.