PHP básico

Decidir y repetir

Lección 3 de 8 · 14 min

La ficha que no siempre dice lo mismo

Una ficha de producto tiene que mostrar el botón de comprar cuando hay existencias, un aviso de «últimas unidades» cuando quedan pocas y un «agotado» sin botón cuando no queda ninguna. Es una sola página que se comporta de tres maneras según un número.

Eso se escribe con condiciones: la instrucción con la que el programa elige un camino u otro.

La ficha de producto, decidiendo
<?php
$existencias = 2;

if ($existencias === 0) {
    echo 'Agotado';
} elseif ($existencias <= 3) {
    echo 'Últimas unidades: quedan ' . $existencias;
} else {
    echo 'Disponible';
}
Resultado
Últimas unidades: quedan 2

PHP evalúa las condiciones en orden y se queda en la primera que se cumple. Por eso el === 0 va primero: si estuviera después del <= 3 nunca se ejecutaría, porque 0 también es menor o igual que 3.

Ese detalle -el orden de las condiciones- es la causa de la mitad de los errores de lógica de un principiante. El otro medio es el que viene ahora.

Los dos iguales y los tres iguales

Ya viste que un = asigna. Para comparar hay dos operadores, y la diferencia importa:

== pregunta «¿valen lo mismo?» y acepta que sean de tipos distintos. === pregunta «¿valen lo mismo y son del mismo tipo?».

La misma comparación, con y sin tipo
<?php
var_dump('5' == 5);    // el texto "5" y el número 5
var_dump('5' === 5);
var_dump(0 == 'a');    // en PHP 8 esto cambió
Resultado
bool(true)
bool(false)
bool(false)

La última línea es historia reciente y explica por qué encontrarás tutoriales que dicen lo contrario: hasta PHP 7, 0 == 'a' daba true, porque PHP convertía la letra a número y le daba 0. Desde PHP 8.0 da false.

Ese cambio arregló una fuente enorme de fallos de seguridad: comparar así una contraseña o un código de verificación podía dar «coinciden» sin coincidir.

Usa === siempre, y == solo cuando sepas exactamente por qué lo necesitas. No cuesta nada y te ahorra la clase de error que aparece meses después, con datos reales, y que es dificilísimo de encontrar.

Los comparadores que vas a usar

Comparar

=== igual e igual tipo · !== distinto o de otro tipo.

< > <= >= para números y fechas.

Combinar

&& exige que se cumplan las dos condiciones; || con que se cumpla una.

! delante invierte: !$pagado es «no está pagado».

Cuando puede no haber dato

?? devuelve lo de la derecha si lo de la izquierda no existe o es null:

$ciudad = $datos['ciudad'] ?? 'Sin especificar';

Es de lo más útil del lenguaje y evita medio archivo de comprobaciones.

Cuando el mismo dato tiene muchos caminos

Encadenar seis elseif para traducir un estado a un texto se lee fatal. Para eso está match, que existe desde PHP 8 y compara de forma estricta, como el ===:

match: un valor, muchos resultados
<?php
$estado = 'en_camino';

$texto = match ($estado) {
    'pendiente'  => 'Esperando pago',
    'pagado'     => 'Pago confirmado',
    'en_camino'  => 'Va en camino',
    'entregado'  => 'Entregado',
    default      => 'Estado desconocido',
};

echo $texto;
Resultado
Va en camino

match y switch: cuál usar

La diferencia que importa

switch compara con == -sin mirar el tipo- y match con ===. Por eso match es la opción por defecto hoy: es coherente con la regla de la comparación estricta.

Además match devuelve un valor, así que se asigna directamente a una variable, como en el ejemplo.

El break que se olvida

En switch, si olvidas el break al final de un caso, la ejecución sigue hacia el caso siguiente y ejecuta también ese. Es un error clásico y no avisa.

match no tiene ese problema: no existe el break.

Si el valor no está en la lista

match sin default lanza un error cuando llega un valor que no previste. Suena incómodo y es una ventaja: te enteras el día que aparece un estado nuevo, en vez de mostrar una ficha en blanco.

Repetir sin escribirlo cien veces

La otra mitad de la lección: hacer lo mismo varias veces. Un ciclo repite un bloque mientras se cumpla una condición.

El más directo es for, cuando sabes cuántas vueltas quieres:

for: un número conocido de vueltas
<?php
for ($i = 1; $i <= 3; $i++) {
    echo 'Cuota ' . $i . " de 3\n";
}
Resultado
Cuota 1 de 3
Cuota 2 de 3
Cuota 3 de 3

Las tres partes entre paréntesis son: dónde empieza ($i = 1), hasta cuándo sigue ($i <= 3) y qué pasa en cada vuelta ($i++, que suma uno).

Cuando no sabes cuántas vueltas serán, sino que hay que repetir mientras ocurra algo, se usa while:

while: mientras se cumpla la condición
<?php
$saldo = 50000;

while ($saldo >= 20000) {
    $saldo = $saldo - 20000;
    echo 'Descontados 20.000. Queda: ' . $saldo . "\n";
}
Resultado
Descontados 20.000. Queda: 30000
Descontados 20.000. Queda: 10000

Si dentro del while nunca cambia lo que se compara, el ciclo no termina jamás. El servidor da vueltas hasta que se acaba su tiempo límite y la página muere a medias.

Antes de escribir un while, responde a esta pregunta: ¿qué línea de aquí dentro hace que la condición deje de cumplirse? En el ejemplo es la que baja el saldo. Si no sabes señalarla, tienes un ciclo infinito.

Repasa antes del cuestionario

Piensa la respuesta y luego haz clic en la tarjeta.

Compruébalo tú mismo

De un formulario llega la cantidad como texto: '0'. Escribes if ($cantidad === 0). ¿Qué ocurre?

¿Por qué la condición === 0 va antes que <= 3 en la ficha del producto?

Escribes un while y la página se queda cargando hasta que da un error de tiempo. ¿Qué revisas primero?

Lo que sigue

Ya sabes decidir y repetir, pero con una variable por dato. Un pedido de doce artículos necesitaría doce variables, y eso no se sostiene. En la siguiente lección guardas muchos datos en una sola variable y los recorres de una pasada.

Siguiente: Arreglos y funciones

Continuar ← Variables, tipos y texto