Curso de PHP gratis · Capítulo 5 de 13 · con Agente Branch
Condicionales en PHP: if, else, switch y match
Un programa que siempre hace lo mismo sirve de poco. Con if, switch y match tu código decide qué hacer según los datos.
Si... entonces
if ejecuta un bloque de código solo si una condición es verdadera:
if (condición) { // se ejecuta si la condición es true }
La condición se escribe entre paréntesis y el bloque entre llaves. Por convención, el contenido del bloque va indentado (4 espacios): PHP no lo necesita, pero las personas sí.
Puedes usar cualquier comparación (<, ==, ===...) o cualquier valor: PHP lo convierte a bool con las reglas que viste en el Laboratorio.
<?php
$bateria = 15;
if ($bateria < 20) {
echo "¡Batería baja! Volviendo a la base\n";
}
if ($bateria > 90) {
echo "Esto no se imprime\n";
}
echo "Fin de la comprobación\n";¡Batería baja! Volviendo a la base Fin de la comprobación
else y elseif
else es el "si no". elseif encadena más condiciones:
if ($nota >= 9) { ... } elseif ($nota >= 5) { ... } else { ... }
PHP evalúa las condiciones en orden y ejecuta solo el primer bloque cuya condición sea verdadera. Los demás se saltan aunque también se cumplieran. Por eso el orden importa: pon primero los casos más concretos.
Usa la Lupa paso a paso para ver qué líneas se ejecutan y cuáles se saltan.
<?php
$nota = 7;
if ($nota >= 9) {
echo "Sobresaliente\n";
} elseif ($nota >= 7) {
echo "Notable\n";
} elseif ($nota >= 5) {
echo "Aprobado\n";
} else {
echo "Suspenso\n";
}Notable
Si $nota = 9, pero hubiéramos puesto primero if ($nota >= 5) y luego elseif ($nota >= 9), ¿qué se imprimiría?
- Sobresaliente
- Aprobado
- Las dos
Ver respuesta
B. Aprobado
La primera condición (9 >= 5) ya es verdadera: se ejecuta ese bloque y el resto se salta. El orden importa.
Verdades a medias
En un if puedes poner cualquier valor, no solo comparaciones: if ($cantidad). PHP lo convierte a bool: es false si vale 0, 0.0, "", "0", [] o null.
Es cómodo, pero peligroso. Imagina que $cantidad viene de un formulario y vale "0": if ($cantidad) lo trata como "no hay cantidad". A veces es lo que quieres... y a veces es un bug.
Para comprobar si una variable existe, usa isset(); para comprobar si está "vacía" (no existe o es falsa), empty().
Sé explícito: if ($cantidad > 0) o if ($nombre !== "") expresan mejor tu intención que if ($cantidad).
<?php
$cantidad = "0";
if ($cantidad) {
echo "Hay pedido\n";
} else {
echo "No hay pedido (¿seguro?)\n";
}
var_dump(isset($cantidad), empty($cantidad));
var_dump(isset($nada), empty($nada));No hay pedido (¿seguro?) bool(true) bool(true) bool(false) bool(true)
Combinar condiciones
Con && (y), || (o) y ! (no) construyes condiciones complejas:
if ($edad >= 18 && $tieneEntrada) { ... } if ($esFestivo || $esDomingo) { ... } if (!$lloviendo) { ... }
Usa paréntesis para que se entienda el orden: ($a || $b) && $c.
Recuerda el cortocircuito: en $divisor != 0 && $total / $divisor > 2, si el divisor es 0 la división nunca se ejecuta. El orden de las condiciones puede evitar errores.
<?php
$edad = 16;
$conPadres = true;
if ($edad >= 18 || ($edad >= 14 && $conPadres)) {
echo "Puede entrar al molino\n";
}
$divisor = 0;
if ($divisor != 0 && 10 / $divisor > 2) {
echo "Grande\n";
} else {
echo "Sin división peligrosa\n";
}Puede entrar al molino Sin división peligrosa
La trampa del =
El bug más famoso de las condiciones: escribir = (asignar) en vez de == (comparar).
if ($x = 5) { ... }
Esto no compara: guarda 5 en $x, y como una asignación devuelve el valor asignado (5, que es verdadero), el if se cumple siempre. Y encima has machacado $x.
¿Por qué PHP lo permite? Porque a veces es útil asignar dentro de una condición (lo verás con los bucles). Pero el 99% de las veces es un error. Algunos programadores escriben if (5 == $x) ("condición Yoda") para que un = olvidado dé error, porque no se puede asignar a un 5.
<?php
$x = 1;
if ($x = 5) {
echo "¡Siempre entra! Y ahora x vale $x\n";
}
$y = 1;
if ($y == 5) {
echo "No entra\n";
} else {
echo "Comparación correcta, y sigue valiendo $y\n";
}¡Siempre entra! Y ahora x vale 5 Comparación correcta, y sigue valiendo 1
switch
switch compara un valor con varios casos:
switch ($dia) { case 1: echo "Lunes"; break; case 2: echo "Martes"; break; default: echo "Otro día"; }
Dos cosas que debes saber:
- Hace falta
break. Sin él, la ejecución "se cae" al siguientecase(fall-through) y ejecuta su código también. A veces se hace a propósito para agrupar casos. - Compara con
==(débil), no con===. Así queswitch ("1")entra encase 1:.
<?php
$dia = 2;
switch ($dia) {
case 1:
echo "Lunes\n";
break;
case 2:
case 3:
echo "Martes o miércoles\n";
break;
default:
echo "Otro día\n";
}
switch ("1") {
case 1:
echo "switch usa ==\n";
break;
}Martes o miércoles switch usa ==
match (PHP 8)
match es el hermano moderno de switch, y es mejor en casi todo:
$texto = match ($dia) { 1 => "Lunes", 2, 3 => "Martes o miércoles", default => "Otro día", };
- Es una expresión: devuelve un valor que puedes guardar o imprimir.
- Compara con
===(estricto). - No necesita
break: nunca se "cae" al siguiente brazo. - Si ningún brazo coincide y no hay
default, lanza un error (UnhandledMatchError) en vez de seguir en silencio.
Truco: match (true) permite usar condiciones en los brazos: $n < 5 => ....
<?php
$dia = 3;
echo match ($dia) {
1 => "Lunes",
2, 3 => "Martes o miércoles",
default => "Otro día",
}, "\n";
$peso = 42;
$talla = match (true) {
$peso < 10 => "pequeño",
$peso < 50 => "mediano",
default => "grande",
};
echo "Saco $talla\n";
echo match ("1") { 1 => "igual", default => "match usa ===" }, "\n";Martes o miércoles Saco mediano match usa ===
¿Qué diferencia NO es cierta entre switch y match?
matchcompara con===matchdevuelve un valormatchnecesitabreaken cada brazo- Sin coincidencia ni default,
matchlanza un error
Ver respuesta
C. match necesita break en cada brazo
match nunca necesita break: cada brazo es independiente. Es switch el que lo necesita.
El ternario
Para decisiones cortas que eligen entre dos valores, el operador ternario:
$estado = $bateria > 50 ? "ok" : "cargar";
Se lee "¿condición? valor si sí : valor si no".
Su versión corta ?: (el operador Elvis) devuelve el primer valor si es verdadero y si no el segundo: $nombre ?: "anónimo".
Y no lo confundas con ??: ?? mira si existe y no es null; ?: mira si es verdadero (así que 0 o "" pasan al segundo).
No anides ternarios sin paréntesis: PHP 8 lo prohíbe porque era imposible de leer.
<?php
$bateria = 30;
$estado = $bateria > 50 ? "ok" : "cargar";
echo "Estado: $estado\n";
$apodo = "";
echo $apodo ?: "anónimo", "\n";
echo $apodo ?? "anónimo", "|\n";Estado: cargar anónimo |
BIT-8 toma decisiones
Con condiciones, BIT-8 puede reaccionar a lo que tiene debajo:
puede_cosechar()devuelvetruesi hay algo maduro.que_hay()devuelve el cultivo:HIERBA,ZANAHORIA... onullsi no hay nada.suelo()devuelve"cesped"o"tierra".
(Para usar que_hay() y suelo() en tu granja necesitarás el Escáner de suelo del Taller.)
Si cosechas algo que no está maduro, lo pierdes. ¡Pregunta antes!
<?php if (puede_cosechar()) { cosechar(); } else { decir("Aún está verde"); } $planta = que_hay(); if ($planta === ZANAHORIA) { decir("¡Una zanahoria!"); } elseif ($planta === null) { decir("Aquí no hay nada"); }
Ejercicios de Condicionales en PHP resueltos
Intenta resolverlos antes de mirar la solución. En el juego puedes ejecutarlos y comprobarlos automáticamente.
Misión del dron 1. Solo lo maduro
En la columna de BIT-8 hay hierba madura y hierba verde mezcladas. Si cosechas la verde, se estropea.
BIT-8 está en (0, 0). Recorre su columna hacia el NORTE (3 casillas) y cosecha solo la hierba madura. No cortes nada verde.
Esta misión mueve al dron BIT-8 por un campo de cultivo: juégala en PHPlay para ver tu código animado.
Pistas
- En cada casilla:
if (puede_cosechar()) { cosechar(); }y luegomover(NORTE);. - Tendrás que repetir el bloque tres veces. (En el Molino aprenderás a no repetirte.)
Ver solución
<?php
if (puede_cosechar()) {
cosechar();
}
mover(NORTE);
if (puede_cosechar()) {
cosechar();
}
mover(NORTE);
if (puede_cosechar()) {
cosechar();
}
Encargo 2. El control del puente
El Guardia te deja escribir sus normas. Las variables $edad (int) y $salvoconducto (bool) ya existen.
Imprime:
Pasasi la edad es 18 o más.Pasa con escoltasi tiene 14 o más y tiene salvoconducto.No pasaen cualquier otro caso.
Pistas
- Empieza por el caso más general:
if ($edad >= 18). - Después:
elseif ($edad >= 14 && $salvoconducto).
Ver solución
<?php
if ($edad >= 18) {
echo "Pasa";
} elseif ($edad >= 14 && $salvoconducto) {
echo "Pasa con escolta";
} else {
echo "No pasa";
}
Encargo 3. Notas con match
La escuela del valle necesita convertir notas numéricas en palabras. $nota (de 0 a 10) ya existe.
Usando match, imprime:
Suspensosi es menor que 5Aprobadosi es 5 o 6Notablesi es 7 u 8Sobresalientesi es 9 o 10
Pistas
echo match (true) { $nota < 5 => "Suspenso", ... };- También puedes listar valores:
5, 6 => "Aprobado".
Ver solución
<?php
echo match (true) {
$nota < 5 => "Suspenso",
$nota <= 6 => "Aprobado",
$nota <= 8 => "Notable",
default => "Sobresaliente",
};
Predicción 4. El switch que se cae
Un aprendiz olvidó algunos break. ¿Qué imprime su programa?
Elige la salida.
<?php
$dia = 2;
switch ($dia) {
case 1:
echo "Lunes ";
case 2:
echo "Martes ";
case 3:
echo "Miércoles ";
break;
default:
echo "Otro";
}MartesMartes MiércolesLunes Martes MiércolesMartes Miércoles Otro
Ver solución
Martes Miércoles
Entra en el case 2 y, sin break, cae al 3, donde por fin hay un break.
Caza de bugs 5. El if tramposo
Este programa debería avisar solo si el pedido es de 5 sacos. Pero siempre dice "grande" y encima cambia el pedido.
Arregla la condición para que, con $pedido = 0, imprima exactamente:
Pedido pequeño Pedido: 0
Código de partida:
<?php
$pedido = 0;
if ($pedido = 5) {
echo "Pedido grande\n";
} else {
echo "Pedido pequeño\n";
}
echo "Pedido: $pedido\n";
Pistas
=guarda un valor. Para comparar usa==o, mejor,===.
Ver solución
<?php
$pedido = 0;
if ($pedido === 5) {
echo "Pedido grande\n";
} else {
echo "Pedido pequeño\n";
}
echo "Pedido: $pedido\n";
Misión del dron 6. Siembra condicional
En la columna de BIT-8 hay casillas de césped con hierba madura y casillas de tierra vacía.
Recorre la columna (3 casillas hacia el NORTE). En cada casilla: si el suelo es "tierra", planta una ZANAHORIA; si no, cosecha si se puede. No debe fallar ninguna acción.
Esta misión mueve al dron BIT-8 por un campo de cultivo: juégala en PHPlay para ver tu código animado.
Pistas
if (suelo() === "tierra") { plantar(ZANAHORIA); } elseif (puede_cosechar()) { cosechar(); }
Ver solución
<?php
if (suelo() === "tierra") {
plantar(ZANAHORIA);
} elseif (puede_cosechar()) {
cosechar();
}
mover(NORTE);
if (suelo() === "tierra") {
plantar(ZANAHORIA);
} elseif (puede_cosechar()) {
cosechar();
}
mover(NORTE);
if (suelo() === "tierra") {
plantar(ZANAHORIA);
} elseif (puede_cosechar()) {
cosechar();
}
Chuleta: lo esencial
if (cond) { } elseif (cond) { } else { }: se ejecuta solo el primer bloque verdadero.- Valores falsos:
false 0 0.0 "" "0" [] null. Sé explícito:if ($n > 0). isset($x): existe y no es null.empty($x): no existe o es falso.&&,||,!con paréntesis. El cortocircuito puede proteger operaciones.if ($x = 5)asigna (siempre verdadero). Compara con==o===.switch: compara con==, necesitabreak(si no, fall-through),default.match: expresión, compara con===, sinbreak, error si no hay coincidencia.match (true)para rangos.- Ternario:
cond ? a : b. Elvis:$a ?: $b. Null coalescing:$a ?? $b.