IRIsrael RivasMatemáticas · TecnologíaEntrarMaestro

Entrar

¿Es tu primera vez? Regístrate · ¿No apareces en la lista? Entra escribiendo tu nombre

Estudia por tu cuenta · Programación · curso 23 de 24

PHP: la página que piensa

Una página HTML siempre dice lo mismo. Una página PHP se arma en el servidor cada vez que alguien la pide, y por eso puede saludarte por tu nombre, contar tus estrellas o decir la hora. Aquí aprendes el lenguaje con el que está hecho este sitio: variables, operaciones, condicionales, bucles, arreglos, funciones, formularios y cómo leer los errores.

<?php\n  echo "Hola, $nombre";\n?>

Antes de empezar: conviene haber llevado el curso de HTML y CSS (PHP escribe HTML) y algo de Python: muchas ideas son las mismas, solo cambia cómo se escriben.

1

Navegador y servidor: dónde corre PHP

Lección 1 de 9

Un archivo HTML llega al navegador tal cual, siempre igual. Un archivo PHP primero pasa por el servidor: ahí se ejecuta, arma el HTML y eso es lo que te llega. Por eso puede cambiar cada vez.

Lo que hay que saber

Cuando entras a israelrivas.org/juegos pasan tres cosas. Tu navegador (Chrome, Safari, el que uses) le pide la página a una computadora que está prendida todo el día en otro lado: el servidor. El servidor arma la página y se la manda. El navegador la pinta.

Tu navegadorsolo entiende HTMLpinta lo que recibeServidoraquí corre PHP2 · arma la página1 · pide /juegos3 · manda HTML listo
El navegador pide, el servidor ejecuta PHP y manda HTML, el navegador lo pinta

Con HTML y CSS (curso de HTML y CSS) el servidor solo entrega el archivo tal cual: la página es fija, dice lo mismo a todos y a todas horas. Con PHP, el servidor ejecuta un programa antes de mandar nada. Ese programa escribe el HTML pedazo por pedazo, y puede escribir cosas distintas según quién pregunta, qué día es o qué hay guardado. La sala de juegos y tu tablero los arma PHP antes de mandártelos: por eso tu tablero trae tu nombre y tus estrellas, y el de tu compañero trae las suyas, aunque los dos pidan la misma dirección.

Un archivo PHP termina en .php y es HTML normal con pedazos de programa adentro. Los pedazos van entre <?php y ?>. Lo que está afuera se manda tal cual; lo que está adentro se ejecuta. Para escribir algo desde el programa se usa echo. Mira la página que dice la fecha:

<p>Hoy es <?php echo date("d/m/Y"); ?></p>
Sale (lo que recibe el navegador):
<p>Hoy es 21/10/2026</p>

Fíjate: el navegador nunca ve la palabra echo ni la función date. Recibe un párrafo normal con la fecha ya escrita. Mañana, el mismo archivo, sin tocarlo, dirá otra fecha. Eso es «la página que piensa». date es una función que ya viene en PHP: le dices con letras qué quieres (d día, m mes, Y año, H hora) y te da el texto.

HTML se manda tal cual. PHP se ejecuta en el servidor, y lo que echo escribe es lo que llega al navegador.Si en tu pantalla ves la palabra echo, el PHP no se ejecutó: lo abriste sin servidor.

Cómo probarlo. Si guardas hola.php y lo abres con doble clic, el navegador te enseña el código tal cual, o una página vacía: el navegador no entiende PHP, solo el servidor. Necesitas uno de estos dos caminos:

  1. Instalar un servidor en tu compu: XAMPP (gratis, para Windows y Mac). Guardas tu archivo en su carpeta htdocs y entras a localhost/hola.php en el navegador. «localhost» quiere decir «el servidor que está en esta misma máquina».
  2. Un hosting con PHP (así está israelrivas.org): subes el archivo y entras desde cualquier lado.

Dos reglas de escritura desde hoy: cada instrucción de PHP termina en punto y coma (;), y lo que empieza con // es un comentario, una nota para ti que PHP ignora.

Así se hace, paso a paso

La página que saluda según la hora

<?php
$hora = date("H");   // la hora, de 00 a 23
?>
<h1>Hola</h1>
<p>Son las <?php echo $hora; ?> horas.</p>

Paso 1 · El servidor abre el archivo y ve <?php. Ejecuta lo que sigue: date("H") da la hora (digamos que son las 16) y se guarda en la cajita $hora.

Paso 2 · Llega al ?>. Lo que sigue es HTML: lo manda tal cual, <h1>Hola</h1>.

Paso 3 · Otro pedazo de PHP. echo $hora escribe 16 justo en ese lugar del párrafo.

Sale:
<h1>Hola</h1>
<p>Son las 16 horas.</p>

El navegador pinta «Hola» y «Son las 16 horas.» A las 9 de la mañana el mismo archivo, sin cambiarle nada, diría «Son las 09 horas.»

Cuidado con esto

Abrir el archivo con doble clic. Ves el código o una página vacía y crees que PHP «no sirve». Sirve; lo que falta es el servidor. Usa localhost con XAMPP o un hosting.

Escribir mal la etiqueta de apertura. < ?php con espacio, o <php sin signo de interrogación. PHP no la reconoce y manda todo ese pedazo como texto.

Olvidar el punto y coma. echo "Hola" sin ; y luego otra instrucción: PHP se detiene con un Parse error. Lo ves con calma en la lección de errores.

Ejercicios

  1. ¿Qué recibe el navegador?
    <p>Dos más dos son <?php echo 2 + 2; ?></p>
    ver la respuesta
    <p>Dos más dos son 4</p>
    En pantalla se lee «Dos más dos son 4».
    Cómo se llega
    1. Lo de fuera de <?php ?> se manda tal cual.
    2. echo 2 + 2 calcula y escribe 4 en ese lugar.
    3. El navegador nunca ve el echo.
  2. ¿Qué sale?
    <?php echo "2 + 2"; ?>
    ver la respuesta
    2 + 2 (tal cual, con el signo)
    Cómo se llega
    1. Lo que va entre comillas es texto, no una cuenta.
    2. PHP lo escribe letra por letra: 2 + 2.
  3. ¿Qué falta?
    <?php echo "Hola" echo " Ana"; ?>
    ver la respuesta
    El punto y coma después de "Hola": echo "Hola"; echo " Ana";
    Cómo se llega
    1. Cada instrucción termina en ;.
    2. Sin él, PHP encuentra el segundo echo donde esperaba el ; y da Parse error.
  4. Guardaste saludo.php en el escritorio, lo abriste con doble clic y ves tu código escrito en la pantalla. ¿Qué pasó y cómo lo arreglas?
    ver la respuesta
    No hay servidor: el navegador no ejecuta PHP. Ponlo en la carpeta htdocs de XAMPP y entra a localhost/saludo.php (o súbelo a un hosting).
    Cómo se llega
    1. El navegador solo entiende HTML.
    2. PHP lo ejecuta el servidor; sin servidor, el archivo es solo texto.
  5. Escribe el programa que muestre un título «Mi página» y debajo un párrafo con la fecha de hoy.
    ver la respuesta
    <h1>Mi página</h1>
    <p>Hoy es <?php echo date("d/m/Y"); ?></p>
    Cómo se llega
    1. El título es HTML normal.
    2. Dentro del párrafo abres PHP, echo date(...) y cierras.
  6. Tu tablero de /mi y el de tu compañera tienen exactamente la misma dirección, y cada quien ve su nombre y sus estrellas. ¿Cómo es posible?
    ver la respuesta
    Porque la página no está guardada fija: PHP la arma en el servidor cada vez que alguien la pide, y mira quién entró para escribir su nombre y sus estrellas.
    Cómo se llega
    1. Misma dirección = mismo archivo .php.
    2. El programa se ejecuta en cada visita y escribe HTML distinto según quién es.
2

Variables y tipos

Lección 2 de 9

Una variable es una cajita con nombre que empieza con $. Guarda un valor, y el valor tiene tipo: entero, decimal, texto, verdadero/falso o nada.

Lo que hay que saber

En Python escribías nombre = "Ana". En PHP es casi igual, pero toda variable lleva $ al principio: $nombre = "Ana";. El $ le dice a PHP «esto es una cajita». El signo = no es «igual a»: es «guarda esto aquí».

<?php
$nombre = "Ana";
$edad = 12;
$altura = 1.52;
$tiene_hermanos = true;
$mascota = null;
echo $nombre;
?>
Sale:
Ana

Cada valor tiene un tipo. PHP tiene cinco básicos:

TipoQué esEjemplos
intnúmero entero12, −3, 0
floatnúmero con punto decimal1.52, 3.0
stringtexto, entre comillas"Ana", "12"
boolverdadero o falsotrue, false
nullnada: la cajita vacíanull

Para ver qué tiene una cajita y de qué tipo es, usa var_dump. Es tu lupa; cada var_dump escribe en su propio renglón:

var_dump($edad);
var_dump($altura);
var_dump($nombre);
var_dump($tiene_hermanos);
var_dump($mascota);
Sale:
int(12)
float(1.52)
string(3) "Ana"
bool(true)
NULL

El 3 de string(3) es cuántas letras tiene. Ojo: "12" entre comillas es texto, no número: var_dump dice string(2) "12". Es la cajita con un papelito que dice «12», no doce cosas.

Comillas dobles y simples no son iguales. Con comillas dobles, PHP busca variables adentro y las cambia por su valor; también entiende \n, que es «cambio de renglón». Con comillas simples escribe todo tal cual:

echo "Hola $nombre\n";
echo 'Hola $nombre';
Sale:
Hola Ana
Hola $nombre

Para pegar textos y variables también está el punto: "Hola " . $nombre . "!" da Hola Ana!. En Python pegabas con +; en PHP el + es solo para sumar, y el punto es para pegar.

$ para variables. Comillas dobles cambian $nombre por su valor; comillas simples no. El punto pega textos."Tengo $edad años" funciona. 'Tengo $edad años' escribe la palabra $edad.

PHP convierte solo. Si sumas "3" + 4, PHP ve que "3" parece número y da 7. Y "3" . 4 da 34 (pegó, no sumó). Es cómodo, pero engaña: cuando un formulario te manda "3", tú crees que es número y es texto; con == el 7 y el "7" se ven iguales y con === no (lo ves en la lección de condicionales). Y si el texto no parece número, "hola" + 4, el programa se rompe. Por eso conviene saber siempre de qué tipo es cada cajita: var_dump, y convertir a propósito con (int) o (float) cuando haga falta: (int)"3" es el número 3.

Así se hace, paso a paso

Seguir las cajitas

$a = 5;
$b = $a;
$a = $a + 1;
echo "a vale $a y b vale $b";

Paso 1 · $a = 5. La cajita a guarda 5.

Paso 2 · $b = $a. La cajita b recibe una copia de lo que hay en a: 5. Son dos cajitas separadas.

Paso 3 · $a = $a + 1. PHP primero calcula el lado derecho: toma el 5 de a, suma 1, da 6. Luego guarda el 6 en a. La b no se entera: sigue con 5.

Paso 4 · echo con comillas dobles. Cambia $a por 6 y $b por 5.

Sale:
a vale 6 y b vale 5

Guardar es copiar. Cambiar una cajita después no cambia la otra.

Cuidado con esto

Olvidar el $. nombre = "Ana"; sin el signo da Parse error. En PHP, sin $ no hay variable.

Comillas simples cuando querías el valor. echo 'Hola $nombre'; imprime la palabra $nombre con todo y signo. Si quieres el valor: comillas dobles, o pega con punto.

Pegar con +. "Hola " + $nombre no pega: intenta sumar y rompe el programa. En Python era +; en PHP es punto.

Ejercicios

  1. ¿Qué sale?
    $x = 4;
    $y = 3;
    echo $x * $y;
    ver la respuesta
    12
    Cómo se llega
    1. $x guarda 4 y $y guarda 3.
    2. 4 × 3 = 12.
  2. ¿Qué sale?
    $fruta = "mango";
    echo 'Me gusta el $fruta';
    ver la respuesta
    Me gusta el $fruta
    Cómo se llega
    1. Comillas simples: no cambia la variable por su valor.
    2. Escribe todo tal cual, con el signo $.
  3. ¿Qué escribe var_dump("7")? ¿Y var_dump(7)?
    ver la respuesta
    string(1) "7" y int(7)
    Cómo se llega
    1. Con comillas es texto de una letra.
    2. Sin comillas es un número entero.
  4. Corrige el error:
    edad = 13;
    echo "Tengo $edad años";
    ver la respuesta
    Falta el $: $edad = 13;
    Cómo se llega
    1. Toda variable lleva $ también al guardarla.
    2. Sin él, PHP da Parse error.
  5. ¿Qué sale?
    echo "4" + "5";
    echo "4" . "5";
    ver la respuesta
    945 (primero 9, luego 45 pegado)
    Cómo se llega
    1. "4" + "5": el + suma; PHP convierte los textos a números: 9.
    2. "4" . "5": el punto pega: 45.
    3. Los dos echo salen seguidos, sin espacio: 945.
  6. Escribe el programa que guarde tu nombre y tu grupo en dos variables e imprima «Soy Ana y voy en 1B» pegando con punto.
    ver la respuesta
    $nombre = "Ana";
    $grupo = "1B";
    echo "Soy " . $nombre . " y voy en " . $grupo;
    Cómo se llega
    1. Dos cajitas con $.
    2. Pega texto, variable, texto, variable con puntos (o usa comillas dobles: "Soy $nombre y voy en $grupo").
3

Operaciones y funciones que ya vienen

Lección 3 de 9

PHP calcula como una calculadora que sabe la jerarquía: primero paréntesis y potencias, luego × ÷ y residuo, al final + −. Y trae funciones listas: round, abs, max, min, strlen…

Lo que hay que saber

Con números, PHP hace lo mismo que tu calculadora, con estos signos (en la compu no hay tecla ×, por eso el asterisco):

OperaciónEscribesSale
Suma7 + 29
Resta7 - 25
Multiplicación7 * 214
División7 / 23.5
Residuo (lo que sobra)7 % 21
Potencia2 ** 38
División entera (sin decimales)intdiv(7, 2)3

El % no es porcentaje: es el residuo de la división (curso de Divisiones, lección 3). Sirve, por ejemplo, para saber si un número es par: $n % 2 da 0 si es par y 1 si es impar. La división con / te da el resultado exacto, con decimales si hacen falta: 8 / 2 da 4, pero 7 / 2 da 3.5. Si solo quieres el cociente entero, intdiv.

Jerarquía. PHP respeta el orden que ya conoces de mates: primero paréntesis, luego potencias, luego * / %, al final + −. Así que 2 + 3 * 4 da 14, no 20. Si quieres que sume primero, paréntesis: (2 + 3) * 4 da 20.

Paréntesis → potencias → * / % → + −. Si dudas, pon paréntesis.PHP no se equivoca con la jerarquía; el que se equivoca es quien olvidó el paréntesis.

Funciones que ya vienen. Una función es una orden con nombre: le pasas algo entre paréntesis y te devuelve un resultado. Estas las vas a usar a cada rato:

FunciónQué haceEjemploSale
round($x, 2)redondea a 2 decimales (sin el 2, a entero)round(3.14159, 2)3.14
abs($x)quita el signoabs(-8)8
max(…)el mayormax(4, 9, 2)9
min(…)el menormin(4, 9, 2)2
strlen($t)cuántas letras tiene el textostrlen("hola")4
strtoupper($t)pasa a mayúsculasstrtoupper("hola")HOLA
str_repeat($t, $n)repite el texto n vecesstr_repeat("ja", 3)jajaja

Las que empiezan con str trabajan con textos (string). Puedes meter una función dentro de otra: round(abs(-2.567), 1) primero quita el signo (2.567) y luego redondea (2.6). PHP resuelve de adentro hacia afuera.

Los decimales van con punto, nunca con coma: 3.5. Si escribes 3,5 PHP lo lee como dos cosas separadas y se confunde. Y fíjate en el tipo del resultado: 10 / 4 es float(2.5), pero 10 / 5 es int(2): si sale exacto, es entero.

<?php
$precio = 48.5;
$cuantos = 3;
$total = $precio * $cuantos;
echo "Total: " . $total . " pesos";
?>
Sale:
Total: 145.5 pesos

Así se hace, paso a paso

Repartir 100 pesos entre 3

$dinero = 100;
$personas = 3;
$cada = $dinero / $personas;
$redondo = round($cada, 2);
$sobra = $dinero % $personas;
echo "A cada quien: " . $redondo . ". Sobra: " . $sobra;

Paso 1 · La división. 100 / 3 no es exacta: $cada guarda 33.333333333333 (PHP guarda muchos decimales).

Paso 2 · Redondear. round($cada, 2) deja dos decimales: 33.33.

Paso 3 · El residuo. 100 % 3: el 3 cabe 33 veces (99) y sobra 1.

Paso 4 · Pegar con puntos. Texto, número, texto, número.

Sale:
A cada quien: 33.33. Sobra: 1

/ da el reparto con decimales; % da lo que sobra; round lo deja presentable.

Cuidado con esto

Coma decimal. $precio = 48,5; no es un número para PHP. Siempre punto: 48.5.

Creer que % es porcentaje. 50 % 100 da 50 (el residuo de 50 entre 100), no «la mitad». Para porcentajes multiplicas: $precio * 50 / 100.

Olvidar la jerarquía. $promedio = $a + $b / 2; divide solo a $b. Tiene que ser ($a + $b) / 2.

strlen cuenta bytes, no letras. strlen("más") da 4, porque la á ocupa dos. Para contar letras con acentos o ñ usa mb_strlen("más"), que da 3. Lo mismo: strtoupper no cambia la ñ; mb_strtoupper sí.

Ejercicios

  1. ¿Qué sale?
    echo 5 + 3 * 2;
    ver la respuesta
    11
    Cómo se llega
    1. Primero la multiplicación: 3 × 2 = 6.
    2. 5 + 6 = 11.
  2. ¿Qué sale?
    echo 17 % 5;
    ver la respuesta
    2
    Cómo se llega
    1. 17 ÷ 5 = 3 y sobran 2.
    2. El % da lo que sobra.
  3. ¿Qué sale?
    echo intdiv(17, 5) . " y " . 17 % 5;
    ver la respuesta
    3 y 2
    Cómo se llega
    1. intdiv(17, 5) = 3 (el cociente sin decimales).
    2. 17 % 5 = 2.
    3. Los puntos pegan: 3 y 2.
  4. ¿Qué sale?
    echo round(7 / 3, 2);
    ver la respuesta
    2.33
    Cómo se llega
    1. 7 ÷ 3 = 2.3333…
    2. round a 2 decimales: 2.33.
  5. Corrige el error: quiero el promedio de dos calificaciones.
    $promedio = $a + $b / 2;
    ver la respuesta
    $promedio = ($a + $b) / 2;
    Cómo se llega
    1. Sin paréntesis divide solo $b.
    2. Con paréntesis primero suma y luego divide.
  6. Escribe el programa que guarde tu nombre en una variable e imprima «ANA tiene 3 letras» (con tu nombre).
    ver la respuesta
    $n = "Ana";
    echo strtoupper($n) . " tiene " . strlen($n) . " letras";
    Cómo se llega
    1. strtoupper para las mayúsculas.
    2. strlen para contar.
    3. Pega todo con puntos.
  7. Tres boletos cuestan $85.5 cada uno. Escribe el programa que imprima el total.
    ver la respuesta
    $boleto = 85.5;
    echo "Total: " . $boleto * 3;
    Sale: Total: 256.5
    Cómo se llega
    1. 85.5 × 3 = 256.5.
    2. El * se hace antes de pegar con el punto.
4

Condicionales: if, elseif, else

Lección 4 de 9

if hace una pregunta que PHP responde true o false. Si es true hace lo de sus llaves; si no, salta al else. El programa toma un camino u otro.

Lo que hay que saber

Hasta ahora el programa hace todo de arriba abajo. Con if decide. Es igual que en Python, pero con la pregunta entre paréntesis y llaves para el bloque, en vez de los dos puntos y la sangría:

$edad = 12;
if ($edad >= 12) {
    echo "Ya puedes entrar a secundaria";
} else {
    echo "Todavía no";
}
Sale:
Ya puedes entrar a secundaria

Lo que va dentro de los paréntesis es una pregunta que PHP contesta true o false. Las preguntas se hacen con comparadores:

EscribesPreguntaEjemploDa
==¿valen lo mismo?5 == "5"true
===¿valen lo mismo y son del mismo tipo?5 === "5"false
!=¿son distintos?5 != 6true
<   >¿menor? ¿mayor?3 < 8true
<=   >=¿menor o igual? ¿mayor o igual?8 >= 8true

Con más de dos caminos usas elseif, los que quieras. PHP prueba de arriba abajo y entra en el primero que sea true; los demás ya no los mira, aunque también fueran ciertos:

$calif = 8;
if ($calif >= 9) {
    echo "Excelente";
} elseif ($calif >= 7) {
    echo "Bien";
} elseif ($calif >= 6) {
    echo "Pasaste";
} else {
    echo "A estudiar";
}
Sale:
Bien

8 ≥ 9 es false; 8 ≥ 7 es true: entra ahí e imprime Bien. Ya no pregunta si 8 ≥ 6 (que también sería true). Por eso el orden de los elseif importa: del más exigente al menos.

== contra ===. Esta es la trampa famosa de PHP. Dos iguales comparan el valor y convierten los tipos si hace falta: 7 == "7" es true. Tres iguales comparan valor y tipo: 7 === "7" es false, porque uno es int y el otro string. Como los formularios te mandan todo como texto, decide con calma cuál usas. Lo más seguro: convierte primero lo que necesites con (int) y compara con ===.

== pregunta «¿valen lo mismo?». === pregunta «¿valen lo mismo Y son del mismo tipo?».7 == "7" → true. 7 === "7" → false. 0 == "" → false, pero "" == null → true. Con === no hay sorpresas.

Juntar preguntas. && es «y» (las dos tienen que ser true), || es «o» (basta una), ! es «no» (voltea el resultado):

$edad = 13;
$tiene_permiso = true;
if ($edad >= 12 && $tiene_permiso) {
    echo "Pasas";
}
if ($edad < 12 || !$tiene_permiso) {
    echo "No pasas";
}
Sale:
Pasas

El operador ternario es un if de una sola línea: $msj = $edad >= 12 ? "grande" : "chico"; se lee «¿edad ≥ 12? entonces grande; si no, chico». Por ahora quédate con la idea, para que cuando lo veas en código ajeno sepas qué es.

Las llaves no son adorno. PHP deja escribir un if sin llaves cuando el bloque es una sola línea, pero el día que agregas una segunda línea creyendo que está adentro, no lo está, y no hay ningún error que te avise. Ponlas siempre.

Sigue el programa con la mano. Antes de correrlo, haz una tabla: cada variable con su valor, y en cada pregunta escribe true o false. Así encuentras errores sin computadora, y así te lo voy a pedir en el examen.

Así se hace, paso a paso

Seguir con la mano

$x = 5;
$y = "5";
if ($x == $y) { echo "A"; }
if ($x === $y) { echo "B"; }
if ($x > 3 && $y < 3) { echo "C"; }
if ($x > 3 || $y < 3) { echo "D"; }

Paso 1 · Anota las cajitas. $x es int(5). $y es string(1) "5".

Paso 2 · Una pregunta a la vez.

PreguntaPor quéDaImprime
$x == $y5 y "5" valen lo mismotrueA
$x === $yint y string: tipos distintosfalsenada
$x > 3 && $y < 3true y false: «y» necesita las dosfalsenada
$x > 3 || $y < 3true o false: con una bastatrueD
Sale:
AD

Los echo salen pegados porque nadie puso cambio de renglón: AD.

Cuidado con esto

Un solo = en la pregunta. if ($x = 5) no pregunta: guarda 5 en $x, y como 5 cuenta como true, siempre entra. Pregunta con == o ===.

Creer que "7" === 7. No: el triple compara el tipo, y uno es texto. Si viene de un formulario, conviértelo: (int)$x === 7.

Olvidar las llaves. if ($ok) echo "a"; echo "b"; imprime b siempre, haya o no $ok. Con llaves no pasa.

elseif en el orden equivocado. Si pones primero $calif >= 6, un 10 también entra ahí y nunca llega a «Excelente».

Ejercicios

  1. ¿Qué sale?
    $n = 4;
    if ($n % 2 == 0) {
        echo "par";
    } else {
        echo "impar";
    }
    ver la respuesta
    par
    Cómo se llega
    1. 4 % 2 = 0 (no sobra nada).
    2. 0 == 0 es true: entra al primer bloque.
  2. ¿Qué sale?
    $t = 31;
    if ($t > 35) {
        echo "mucho calor";
    } elseif ($t > 25) {
        echo "calor";
    } else {
        echo "fresco";
    }
    ver la respuesta
    calor
    Cómo se llega
    1. 31 > 35: false, sigue.
    2. 31 > 25: true, entra e imprime calor. Ya no mira el else.
  3. ¿true o false?
    3 == "3"
    3 === "3"
    "abc" == "abc"
    5 != 5
    ver la respuesta
    true, false, true, false
    Cómo se llega
    1. == solo mira el valor: 3 y "3" valen lo mismo.
    2. === también mira el tipo: int y string, distintos.
    3. 5 != 5: no son distintos.
  4. ¿Qué sale?
    $a = 10;
    if ($a > 5 && $a < 8) {
        echo "sí";
    } else {
        echo "no";
    }
    ver la respuesta
    no
    Cómo se llega
    1. 10 > 5 es true, pero 10 < 8 es false.
    2. && necesita las dos: false. Va al else.
  5. Corrige el error:
    if ($edad = 18) {
        echo "mayor de edad";
    }
    ver la respuesta
    if ($edad == 18) o, mejor, if ($edad === 18). Un solo = guarda, no pregunta.
    Cómo se llega
    1. $edad = 18 mete 18 en la cajita y vale 18, que cuenta como true.
    2. Siempre entraría. Con == compara.
  6. Escribe el programa que, con un número guardado en $n, imprima «positivo», «negativo» o «cero».
    ver la respuesta
    if ($n > 0) {
        echo "positivo";
    } elseif ($n < 0) {
        echo "negativo";
    } else {
        echo "cero";
    }
    Cómo se llega
    1. Tres caminos: if, elseif, else.
    2. El cero cae en el else porque no es mayor ni menor que 0.
  7. En una tienda en línea el envío es gratis si la compra llega a $500; si no, cobra $90. Escribe el programa que calcule $pago a partir de $compra.
    ver la respuesta
    if ($compra >= 500) {
        $pago = $compra;
    } else {
        $pago = $compra + 90;
    }
    echo $pago;
    Cómo se llega
    1. «Llega a 500» es mayor o igual: >=.
    2. Si no llega, se suman los 90.
5

Bucles: for, while y foreach

Lección 5 de 9

Un bucle repite un bloque. for cuando sabes cuántas veces; while mientras algo sea cierto; foreach para recorrer una lista. Un contador o acumulador va guardando el resultado.

Lo que hay que saber

En Python escribías for i in range(1, 6). En PHP el for trae tres partes entre paréntesis, separadas por ;: dónde empieza, hasta cuándo sigue y cómo avanza:

for ($i = 1; $i <= 5; $i++) {
    echo $i . " ";
}
Sale:
1 2 3 4 5 

$i++ quiere decir «súmale 1 a $i». El bucle hace esto: pone $i en 1; pregunta ¿$i ≤ 5?; si es true, ejecuta las llaves y luego avanza $i; vuelve a preguntar. Cuando $i llega a 6 la pregunta da false y se sale. Da 5 vueltas. Si escribes $i < 5 da 4: la vuelta de más o de menos es el error más común de los bucles.

while repite mientras la pregunta sea true. Lo usas cuando no sabes de antemano cuántas vueltas serán:

$ahorro = 0;
$semanas = 0;
while ($ahorro < 100) {
    $ahorro = $ahorro + 30;
    $semanas++;
}
echo "Junté $ahorro pesos en $semanas semanas";
Sale:
Junté 120 pesos en 4 semanas

Lo que hay adentro tiene que acercar el bucle a su fin (aquí $ahorro sube cada vuelta). Si nada cambia, la pregunta siempre es true, el bucle nunca termina y la página se queda colgada.

Acumular y contar. Para sumar muchas cosas, una variable empieza en 0 y en cada vuelta le agregas: $suma = $suma + $i, o más corto, $suma += $i. Es el acumulador. Para contar vueltas, $cuenta++: el contador. Los dos se declaran antes del bucle, nunca adentro.

Tabla de seguimiento. Para saber qué hace un bucle sin correrlo, una fila por vuelta:

$suma = 0;
for ($i = 1; $i <= 4; $i++) {
    $suma += $i;
}
echo $suma;
Vuelta$i¿$i ≤ 4?$suma después
11true1
22true3
33true6
44true10
—5false: sale10
Sale:
10

foreach recorre una lista completa sin contador: «para cada $cosa de $lista». Lo ves a fondo en la lección de arreglos:

$frutas = ["mango", "uva", "kiwi"];
foreach ($frutas as $f) {
    echo $f . ", ";
}
Sale:
mango, uva, kiwi, 
for: sé cuántas vueltas. while: mientras se cumpla. foreach: una vez por cada cosa de la lista.Y siempre pregúntate: ¿qué hace que termine?

Un bucle que arma HTML. Aquí es donde PHP brilla. En vez de escribir diez renglones de tabla a mano, el bucle los escribe por ti. Puedes abrir y cerrar PHP a la mitad del bucle; el HTML que queda entre las llaves se manda una vez por vuelta. Así arma el servidor la lista de juegos de la sala: un bucle, y por cada juego una tarjeta.

<table>
<?php for ($i = 1; $i <= 3; $i++) { ?>
  <tr><td>7 x <?php echo $i; ?></td><td><?php echo 7 * $i; ?></td></tr>
<?php } ?>
</table>
Sale:
<table>
  <tr><td>7 x 1</td><td>7</td></tr>
  <tr><td>7 x 2</td><td>14</td></tr>
  <tr><td>7 x 3</td><td>21</td></tr>
</table>

Así se hace, paso a paso

Sumar los pares del 2 al 10

$suma = 0;
for ($i = 2; $i <= 10; $i += 2) {
    $suma += $i;
}
echo $suma;

Paso 1 · Lee las tres partes. Empieza en 2; sigue mientras $i ≤ 10; avanza de 2 en 2 ($i += 2 es «súmale 2»).

Paso 2 · Tabla de seguimiento.

$i¿$i ≤ 10?$suma
2true2
4true6
6true12
8true20
10true30
12false: sale30

Paso 3 · El echo está fuera del bucle, así que imprime una sola vez, al final.

Sale:
30

Cinco vueltas, y el acumulador terminó en 30.

Cuidado con esto

< cuando querías <=. for ($i = 1; $i < 10; $i++) llega al 9, no al 10. Cuenta las vueltas con la mano en las primeras y en las últimas.

No avanzar en el while. while ($x < 10) { echo $x; } sin $x++ es un bucle infinito. La página se cuelga.

Reiniciar el acumulador adentro. Si pones $suma = 0; dentro de las llaves, cada vuelta borra lo anterior y al final solo tienes el último.

El echo en el lugar equivocado. Dentro de las llaves imprime en cada vuelta; fuera, solo al final. Decide cuál quieres.

Ejercicios

  1. ¿Cuántas veces imprime?
    for ($i = 0; $i < 6; $i++) {
        echo "hola ";
    }
    ver la respuesta
    6 veces (i = 0, 1, 2, 3, 4, 5)
    Cómo se llega
    1. Empieza en 0 y sigue mientras sea menor que 6.
    2. 0, 1, 2, 3, 4, 5: seis valores.
  2. ¿Qué vale $s al final?
    $s = 0;
    for ($i = 1; $i <= 3; $i++) {
        $s += $i * 2;
    }
    ver la respuesta
    12
    Cómo se llega
    1. Vuelta 1: $s = 0 + 2 = 2.
    2. Vuelta 2: $s = 2 + 4 = 6.
    3. Vuelta 3: $s = 6 + 6 = 12.
  3. ¿Qué sale?
    $n = 1;
    while ($n < 50) {
        $n = $n * 2;
    }
    echo $n;
    ver la respuesta
    64
    Cómo se llega
    1. 1 → 2 → 4 → 8 → 16 → 32: todos menores que 50, sigue.
    2. 32 × 2 = 64. Ahora 64 < 50 es false: sale.
    3. Imprime 64.
  4. ¿Qué falta?
    $x = 1;
    while ($x < 10) {
        echo $x;
    }
    ver la respuesta
    Avanzar $x dentro del bucle ($x++). Sin eso, $x siempre es 1 y el bucle nunca termina.
    Cómo se llega
    1. La pregunta $x < 10 tiene que volverse false algún día.
    2. Algo adentro debe cambiar $x.
  5. Escribe el programa que imprima la tabla del 8, del 1 al 10, cada renglón como «8 x 3 = 24» dentro de un <li>.
    ver la respuesta
    for ($i = 1; $i <= 10; $i++) {
        echo "<li>8 x $i = " . 8 * $i . "</li>";
    }
    Cómo se llega
    1. Diez vueltas: de 1 a 10 con <=.
    2. En cada vuelta un li con la cuenta y el resultado.
  6. Escribe la cuenta regresiva de Año Nuevo: imprime 10, 9, 8… hasta 1 y al final «¡Feliz año!».
    ver la respuesta
    for ($i = 10; $i >= 1; $i--) {
        echo $i . " ";
    }
    echo "¡Feliz año!";
    Cómo se llega
    1. Empieza en 10, sigue mientras $i ≥ 1, y $i-- le resta 1.
    2. El saludo va fuera del bucle para que salga una sola vez.
6

Arreglos: listas y listas con nombre

Lección 6 de 9

Un arreglo es una lista en una sola variable. Cada cosa tiene su lugar: un número desde 0, o un nombre que tú le pones. foreach los recorre todos.

Lo que hay que saber

Un arreglo (en Python, lista) guarda varias cosas en una sola cajita, entre corchetes y separadas por comas. Para sacar una, dices su lugar:

$frutas = ["mango", "uva", "kiwi"];
echo $frutas[0] . " y " . $frutas[2];
Sale:
mango y kiwi
[0][1][2]"mango""uva""kiwi"$frutas: tres lugares, 0, 1 y 2
La lista $frutas: el primer lugar es el 0

El número entre corchetes es el índice y empieza en 0, no en 1: el primero es [0], el segundo [1]. El último de una lista de 3 es [2]. Si pides [3], PHP avisa «Undefined array key 3» y te da nada.

count dice cuántas cosas hay, y [] = agrega una al final:

$frutas[] = "pera";
echo count($frutas) . " frutas, la última es " . $frutas[3];
Sale:
4 frutas, la última es pera

El último lugar siempre es count − 1: $frutas[count($frutas) - 1].

Arreglos con nombre (asociativos). En vez de números, cada lugar tiene una clave que tú eliges, con =>. Es como el diccionario de Python:

$alumna = ['nombre' => 'Ana', 'grupo' => '1B', 'estrellas' => 14];
echo $alumna['nombre'] . " tiene " . $alumna['estrellas'] . " estrellas";
Sale:
Ana tiene 14 estrellas

Recorrer con foreach. «Para cada clave y valor del arreglo, haz esto». $k recibe la clave y $v el valor, una vuelta por cada cosa:

foreach ($alumna as $k => $v) {
    echo "$k: $v\n";
}
Sale:
nombre: Ana
grupo: 1B
estrellas: 14

Si no necesitas la clave, foreach ($lista as $v) a secas.

El índice empieza en 0. count cuenta. [] = agrega al final. foreach recorre.Lista de 5 cosas: lugares 0, 1, 2, 3, 4. El último es count − 1.

Arreglos dentro de arreglos. Un grupo es una lista de alumnos, y cada alumno es un arreglo con nombre. Así está guardada la sala de juegos de este sitio: una lista de juegos, cada uno con su clave, su nombre y qué hace. Para llegar adentro, dos pares de corchetes:

$grupo = [
  ['nombre' => 'Ana', 'estrellas' => 14],
  ['nombre' => 'Beto', 'estrellas' => 9],
  ['nombre' => 'Caro', 'estrellas' => 20],
];
echo $grupo[1]['nombre'];
Sale:
Beto
foreach ($grupo as $a) {
    echo "<li>" . $a['nombre'] . ": " . $a['estrellas'] . "</li>";
}
Sale:
<li>Ana: 14</li><li>Beto: 9</li><li>Caro: 20</li>

Así se hace, paso a paso

El total de estrellas del grupo

$total = 0;
foreach ($grupo as $a) {
    $total += $a['estrellas'];
}
$promedio = $total / count($grupo);
echo "Total: $total, promedio: " . round($promedio, 1);

Paso 1 · El acumulador en 0, antes del bucle.

Paso 2 · Una vuelta por alumno. $a es Ana: $total = 0 + 14 = 14. $a es Beto: 14 + 9 = 23. $a es Caro: 23 + 20 = 43.

Paso 3 · count($grupo) es 3. 43 / 3 = 14.333…; round a un decimal: 14.3.

Sale:
Total: 43, promedio: 14.3

Así calcula el panel de estadísticas las estrellas de cada grupo: un foreach y un acumulador.

Cuidado con esto

Empezar a contar en 1. $lista[1] es el segundo. El primero es $lista[0].

Pedir un lugar que no existe. En una lista de 3, $lista[3] no existe (Undefined array key). El último es [2], o count − 1.

Clave sin comillas. $alumna[nombre] sin comillas no busca la clave: PHP cree que nombre es otra cosa y se rompe (Undefined constant). Es $alumna['nombre'].

Ejercicios

  1. ¿Qué sale?
    $c = ["rojo", "azul", "verde"];
    echo $c[1];
    ver la respuesta
    azul
    Cómo se llega
    1. [0] rojo, [1] azul, [2] verde.
    2. El índice empieza en 0.
  2. ¿Qué sale?
    echo count([4, 8, 15, 16, 23, 42]);
    ver la respuesta
    6
    Cómo se llega
    1. count cuenta cuántas cosas hay.
    2. Seis números.
  3. ¿Qué está mal?
    $n = ["Ana", "Beto"];
    echo $n[2];
    ver la respuesta
    No hay lugar 2: la lista tiene [0] y [1]. PHP avisa Undefined array key 2.
    Cómo se llega
    1. Dos cosas: lugares 0 y 1.
    2. El último es count − 1 = 1.
  4. ¿Qué sale?
    $h = ['lunes' => 'mates', 'martes' => 'arte'];
    echo $h['martes'];
    ver la respuesta
    arte
    Cómo se llega
    1. La clave martes guarda arte.
  5. ¿Qué sale?
    $x = [3, 5, 7];
    $x[] = 9;
    echo count($x) . "-" . $x[3];
    ver la respuesta
    4-9
    Cómo se llega
    1. [] = agrega el 9 al final, en el lugar [3].
    2. Ahora hay 4 cosas.
  6. Escribe el programa que guarde tus 4 juegos favoritos en una lista y los imprima como <li> numerados desde 1.
    ver la respuesta
    $juegos = ["El blanco", "La recta", "Hanói", "Pixel art"];
    $n = 1;
    foreach ($juegos as $j) {
        echo "<li>$n. $j</li>";
        $n++;
    }
    Cómo se llega
    1. Un contador $n que empieza en 1, aparte del índice.
    2. foreach para recorrer; $n++ en cada vuelta.
  7. Las calificaciones de Toño son [8, 9, 7, 10]. Escribe el programa que imprima su promedio.
    ver la respuesta
    $cal = [8, 9, 7, 10];
    $suma = 0;
    foreach ($cal as $c) {
        $suma += $c;
    }
    echo $suma / count($cal);
    Sale: 8.5
    Cómo se llega
    1. Acumula: 8 + 9 + 7 + 10 = 34.
    2. 34 entre count = 4 → 8.5.
7

Funciones: escribe una vez, usa mil

Lección 7 de 9

Una función es un pedazo de programa con nombre. La escribes una vez y la llamas las veces que quieras. Recibe datos entre paréntesis y devuelve un resultado con return.

Lo que hay que saber

Ya usaste funciones hechas: round, strlen, date. Ahora haces las tuyas. En Python era def; en PHP es function, con llaves:

function doble($x) {
    return $x * 2;
}
echo doble(4) . " y " . doble(doble(5));
Sale:
8 y 20

$x es el parámetro: una cajita que se llena con lo que le mandes al llamar. doble(4) pone 4 en $x y devuelve 8. doble(doble(5)) primero resuelve la de adentro (10) y luego la de afuera (20). return entrega el resultado y termina la función: lo que escribas después de return ya no corre. Si una función no tiene return, devuelve null, o sea nada.

Puede recibir varios parámetros, separados por coma:

function area_triangulo($base, $altura) {
    return $base * $altura / 2;
}
echo area_triangulo(10, 4);
Sale:
20

Valores por omisión. Si un parámetro casi siempre vale lo mismo, dale un valor de fábrica con =. Al llamar, puedes mandarlo o no:

function saluda($nombre, $saludo = "Hola") {
    return "$saludo, $nombre!\n";
}
echo saluda("Ana");
echo saluda("Beto", "Buenas");
Sale:
Hola, Ana!
Buenas, Beto!

echo o return. Una función que hace echo escribe de inmediato y no te deja nada en la mano. Una que hace return te da el valor para que tú decidas: guardarlo, sumarlo, imprimirlo. Casi siempre quieres return.

Funciones que arman HTML. Aquí está el truco de todo este sitio. Una tarjeta de juego es el mismo HTML con otro título y otro texto. Entonces una función la arma y la devuelve como texto:

function tarjeta($titulo, $texto) {
    return '<div class="tarjeta"><h3>' . $titulo . '</h3><p>' . $texto . '</p></div>';
}
echo tarjeta("El blanco", "Llega al objetivo con operaciones");
echo tarjeta("La recta", "Ubica el número");
Sale:
<div class="tarjeta"><h3>El blanco</h3><p>Llega al objetivo con operaciones</p></div><div class="tarjeta"><h3>La recta</h3><p>Ubica el número</p></div>

Por eso en el código de israelrivas.org hay funciones como barra_sitio(), que arma la barra de arriba, o es_pastel(), que dibuja un pastel partido en rebanadas. La barra se escribió una sola vez y aparece en todas las páginas: si la cambio en la función, cambia en todas. Sin funciones tendría que corregir cien archivos uno por uno.

function nombre($parámetros) { … return resultado; }. Escríbelo una vez, llámalo mil.Si copias y pegas el mismo pedazo dos veces, ahí va una función.

Lo de adentro se queda adentro. Las variables que creas dentro de una función no existen afuera, y las de afuera no se ven adentro. Todo entra por los parámetros y sale por el return. Eso es bueno: la función no rompe nada ajeno, y la puedes usar sin recordar cómo está hecha por dentro.

Así se hace, paso a paso

Una función que decide

function nivel($estrellas) {
    if ($estrellas >= 20) {
        return "oro";
    }
    if ($estrellas >= 10) {
        return "plata";
    }
    return "bronce";
}
echo nivel(14) . " " . nivel(25) . " " . nivel(3);

Paso 1 · nivel(14). $estrellas vale 14. ¿14 ≥ 20? No. ¿14 ≥ 10? Sí: return "plata" y la función termina ahí; nunca llega al bronce.

Paso 2 · nivel(25). ¿25 ≥ 20? Sí: return "oro". Se acabó.

Paso 3 · nivel(3). Ninguna de las dos preguntas es true, así que llega al último return: "bronce".

Sale:
plata oro bronce

No hace falta else cuando cada camino termina en return: el primero que se cumple se lleva el resultado.

Cuidado con esto

Olvidar el return. function doble($x) { $x * 2; } calcula y tira el resultado. echo doble(4) no imprime nada.

Usar adentro una variable de afuera. Da Undefined variable. Pásala como parámetro.

Llamar sin paréntesis. echo doble; no llama a la función. Siempre doble(4), aunque no tenga parámetros: hora().

Código después del return. Nunca corre. Si ves que «no entra», revisa si hay un return arriba.

Ejercicios

  1. ¿Qué sale?
    function triple($n) {
        return $n * 3;
    }
    echo triple(7);
    ver la respuesta
    21
    Cómo se llega
    1. $n recibe 7.
    2. 7 × 3 = 21, y return lo entrega al echo.
  2. ¿Qué sale?
    function cuadrado($n) {
        return $n * $n;
    }
    echo cuadrado(3) + cuadrado(4);
    ver la respuesta
    25
    Cómo se llega
    1. cuadrado(3) = 9, cuadrado(4) = 16.
    2. 9 + 16 = 25.
  3. ¿Qué falta?
    function suma($a, $b) {
        $a + $b;
    }
    echo suma(2, 3);
    ver la respuesta
    El return: return $a + $b;. Sin él la función devuelve null y el echo no imprime nada.
    Cómo se llega
    1. La función calcula 5 pero no lo entrega.
    2. return es lo que sale de la función.
  4. ¿Qué sale?
    function saluda($n = "amigo") {
        return "Hola $n";
    }
    echo saluda();
    ver la respuesta
    Hola amigo
    Cómo se llega
    1. No le mandaste nada, así que $n usa su valor por omisión.
    2. Comillas dobles: $n se cambia por amigo.
  5. Escribe la función es_par($n) que devuelva true si el número es par y false si no.
    ver la respuesta
    function es_par($n) {
        return $n % 2 == 0;
    }
    Cómo se llega
    1. $n % 2 da 0 en los pares.
    2. La comparación == 0 ya es true o false: se devuelve directo.
  6. Escribe la función boton($texto, $url) que arme un enlace <a class="boton" href="…">…</a>, y úsala dos veces.
    ver la respuesta
    function boton($texto, $url) {
        return '<a class="boton" href="' . $url . '">' . $texto . '</a>';
    }
    echo boton("Jugar", "/juegos");
    echo boton("Mi tablero", "/mi");
    Cómo se llega
    1. El HTML va en comillas simples porque adentro lleva comillas dobles.
    2. Se pega con puntos la url y el texto.
    3. Dos llamadas, dos botones distintos con el mismo molde.
8

Formularios: recibir lo que escribe el usuario

Lección 8 de 9

Un formulario manda al servidor lo que el usuario escribió. PHP lo recibe en $_POST, lo revisa con calma y responde. Nunca confíes en lo que llega: revísalo y escápalo.

Lo que hay que saber

Hasta aquí tus programas no hablan con nadie. Un formulario (curso de HTML y CSS) deja que el usuario escriba y mande. Con method="post", lo que escribió viaja al servidor y PHP lo encuentra en un arreglo especial: $_POST, con la clave igual al name del campo.

<form method="post">
  <input name="nombre">
  <button>Enviar</button>
</form>
<?php
if (isset($_POST['nombre'])) {
    echo "<p>Hola, " . htmlspecialchars($_POST['nombre']) . "</p>";
}
?>
Sale (después de escribir Ana y apretar Enviar):
<form method="post">
  <input name="nombre">
  <button>Enviar</button>
</form>
<p>Hola, Ana</p>

Esta página se pide dos veces. La primera, el usuario solo llega: $_POST está vacío, isset da false y no se imprime el párrafo; solo ve el formulario. La segunda, apretó Enviar: llega $_POST['nombre'] con "Ana" y la página responde. Mismo archivo, dos comportamientos. Es el ciclo de todo formulario:

pedirel formulariorevisarisset, vacío, númerorespondercon htmlspecialcharssi algo falló, se vuelve a pedir
El ciclo de un formulario: pedir, revisar, responder

isset pregunta «¿existe esta cajita?». Sin él, en la primera visita PHP se queja: Undefined array key "nombre", porque todavía nadie ha mandado nada.

Revisar antes de usar. Lo que manda el usuario puede ser cualquier cosa: vacío, letras donde esperabas número, o algo peor. Antes de usarlo, tres preguntas:

  1. ¿Viene vacío? trim($_POST['nombre']) === '' (trim quita los espacios de las orillas). Si sí, pide que lo llene.
  2. ¿Es número? is_numeric($_POST['edad']). Si no, avisa. Y si sí, conviértelo: (int)$_POST['edad'], porque llega como texto.
  3. ¿Está en el rango que esperas? Una edad entre 1 y 120, una calificación entre 0 y 10.
NUNCA confíes en lo que manda el usuario. Revísalo todo, y escápalo con htmlspecialchars antes de mostrarlo.No porque la gente sea mala, sino porque basta una persona. Y porque los dedos se equivocan.

htmlspecialchars. Si el usuario escribe <b>hola</b> y tú lo imprimes tal cual, el navegador lo entiende como etiqueta: sale «hola» en negritas. Y si escribe una etiqueta <script>, mete un programa en tu página, que verán todos los demás. htmlspecialchars cambia cada < por &lt; y cada > por &gt;, y entonces el navegador los muestra como texto, no los ejecuta. En este sitio, todo lo que escribe un alumno (su nombre, lo que pone en la pizarra) pasa por ahí antes de pintarse.

$texto = "<b>hola</b>";
echo $texto . "\n";
echo htmlspecialchars($texto);
Sale:
<b>hola</b>
&lt;b&gt;hola&lt;/b&gt;

El navegador pinta el primer renglón como hola en negritas (obedeció la etiqueta) y el segundo como <b>hola</b> escrito letra por letra (lo mostró, no lo obedeció). Eso es lo que quieres cuando el texto viene de afuera.

Con method="get" los datos viajan en la dirección (pagina.php?edad=12) y llegan en $_GET. Sirve para búsquedas que se puedan compartir; para contraseñas o datos personales, siempre post.

Así se hace, paso a paso

Tu edad en días

<form method="post">
  <input name="edad"> <button>Calcular</button>
</form>
<?php
if (isset($_POST['edad'])) {
    $edad = trim($_POST['edad']);
    if ($edad === '') {
        echo "<p>Escribe tu edad.</p>";
    } elseif (!is_numeric($edad)) {
        echo "<p>Eso no es un número: " . htmlspecialchars($edad) . "</p>";
    } else {
        $dias = (int)$edad * 365;
        echo "<p>Has vivido unos $dias días.</p>";
    }
}
?>

Paso 1 · Primera visita. No hay $_POST['edad']: isset da false, solo se ve el formulario.

Paso 2 · Manda vacío. isset ahora sí (la cajita existe, aunque vacía); trim deja ''; entra al primer if: «Escribe tu edad.»

Paso 3 · Manda «doce». No está vacío; is_numeric("doce") es false, así que !false es true: «Eso no es un número: doce».

Paso 4 · Manda «12». Es numérico; (int)"12" lo vuelve número; 12 × 365 = 4380.

Sale (caso 4):
<p>Has vivido unos 4380 días.</p>

Un solo archivo atiende los cuatro casos. Pedir, revisar, responder.

Cuidado con esto

Sin isset. echo $_POST['nombre']; en la primera visita da Warning: Undefined array key, porque nadie ha mandado nada todavía.

Olvidar htmlspecialchars. Funciona… hasta que alguien escribe una etiqueta. Es la puerta más común por la que se cuelan programas ajenos en una página.

Creer que $_POST['edad'] es número. Es el texto "12". $edad === 12 da false. Convierte con (int) antes de comparar o calcular.

Revisar solo en el navegador. Que el input diga type="number" no garantiza nada: el usuario puede mandar lo que quiera. La revisión que cuenta es la del servidor, en PHP.

Ejercicios

  1. El campo del formulario es <input name="ciudad"> con method="post". ¿Cómo lees en PHP lo que escribió el usuario?
    ver la respuesta
    $_POST['ciudad']
    Cómo se llega
    1. $_POST es el arreglo con todo lo que mandó el formulario.
    2. La clave es el name del campo.
  2. El usuario escribe <i>Ana</i> en el campo nombre. ¿Qué ve en pantalla con echo htmlspecialchars($_POST['nombre']);? ¿Y sin htmlspecialchars?
    ver la respuesta
    Con htmlspecialchars ve el texto <i>Ana</i> tal cual. Sin él ve Ana en cursiva: el navegador obedeció la etiqueta.
    Cómo se llega
    1. htmlspecialchars cambia < por &lt;: el navegador lo muestra como texto.
    2. Sin escapar, la etiqueta se ejecuta.
  3. ¿Qué falta?
    echo "Hola " . $_POST['nombre'];
    ver la respuesta
    Dos cosas: isset($_POST['nombre']) antes (en la primera visita no existe) y htmlspecialchars al mostrarlo.
    Cómo se llega
    1. Sin isset: Warning en la primera visita.
    2. Sin htmlspecialchars: cualquiera mete etiquetas.
  4. El usuario escribe 12. ¿Qué sale?
    $edad = $_POST['edad'];
    if ($edad === 12) {
        echo "doce";
    }
    ver la respuesta
    Nada. $edad es el texto "12" y === lo compara con el número 12: tipos distintos, false.
    Cómo se llega
    1. Todo lo que llega de un formulario es texto.
    2. Arreglo: (int)$edad === 12, o comparar con == (menos seguro).
  5. ¿true o false? is_numeric("12.5"), is_numeric("doce"), is_numeric("")
    ver la respuesta
    true, false, false
    Cómo se llega
    1. "12.5" parece número con punto: sí.
    2. "doce" son letras. Y el texto vacío no es número.
  6. Escribe la página con un campo name="numero" que, al enviar, diga si el número es par o impar. Revisa que no venga vacío y que sea número.
    ver la respuesta
    <form method="post"><input name="numero"><button>Ver</button></form>
    <?php
    if (isset($_POST['numero'])) {
        $n = trim($_POST['numero']);
        if ($n === '') {
            echo "Escribe un número.";
        } elseif (!is_numeric($n)) {
            echo "Eso no es un número.";
        } elseif ((int)$n % 2 == 0) {
            echo "Es par.";
        } else {
            echo "Es impar.";
        }
    }
    ?>
    Cómo se llega
    1. isset primero.
    2. Luego vacío, luego número.
    3. Al final la pregunta de par con % 2.
9

Leer los errores

Lección 9 de 9

PHP te dice qué salió mal, en qué archivo y en qué línea. Léelo despacio: casi siempre es un ; olvidado, una comilla sin cerrar o una variable mal escrita.

Lo que hay que saber

Equivocarse es parte de programar; lo que distingue a quien sabe es que lee el mensaje en vez de asustarse. Un error de PHP siempre trae tres datos: qué pasó, en qué archivo y en qué línea. Ve primero a esa línea; si ahí no ves nada raro, mira la de arriba, porque muchas veces lo que falta estaba en la anterior.

Parse error: el programa ni empieza. PHP lee todo el archivo antes de ejecutar nada; si hay algo que no entiende, no corre ni una línea:

1  <?php
2  $nombre = "Ana"
3  echo "Hola $nombre";
Sale:
Parse error: syntax error, unexpected token "echo", expecting "," or ";" in hola.php on line 3

Dice línea 3, pero el ; faltaba en la 2: PHP se dio cuenta hasta que encontró echo donde esperaba el punto y coma. «unexpected» es «no esperaba esto»; «expecting» es «esperaba esto otro». Con esas dos palabras ya sabes qué buscar.

MensajeQué pasóQué revisar
syntax error, unexpected token "…", expecting ";"falta un ;la línea anterior a la que dice
syntax error, unexpected end of filecomilla, paréntesis o llave sin cerrar: PHP llegó al final buscándolacuenta comillas y llaves de arriba abajo
Unclosed '{' on line 4la llave que abriste en la 4 no tiene su }ese bloque
Warning: Undefined variable $nombeusaste una variable que no existecómo la escribiste (nombre vs nombe), o si le falta el $ al guardarla
Warning: Undefined array key 3pediste un lugar del arreglo que no existeel índice empieza en 0; o la clave está mal escrita
Fatal error: Uncaught DivisionByZeroError: Division by zerodividiste entre 0el divisor (¿count de una lista vacía?)
Fatal error: Uncaught Error: Call to undefined function sumar()llamaste una función que no existeel nombre, letra por letra
Fatal error: Uncaught TypeError: Unsupported operand types: string + intsumaste texto con número ("hola" + 4)¿querías pegar con punto?

Warning contra Fatal. Un Warning avisa y sigue: la página sale, pero algo quedó vacío o mal. Un Fatal error detiene todo en ese punto: lo de arriba ya salió, lo de abajo no. Un Parse error no deja salir nada.

Comillas sin cerrar. Es la más traicionera: PHP cree que todo lo que sigue es parte del texto, y el error aparece lejos, a veces como «unexpected end of file». Si el mensaje no tiene sentido en su línea, cuenta las comillas de las líneas de arriba.

Buscar el error a la mitad. A veces el programa corre pero da mal, y no hay mensaje. Entonces pones un echo de prueba (o var_dump) a la mitad, para ver qué vale una variable en ese punto: echo "aquí total = $total";. Lo vas moviendo hasta encontrar dónde cambió lo que no debía. Cuando lo arregles, quítalo.

Lee el mensaje: qué, dónde, qué línea. Mira esa línea y la de arriba. Cuenta ; comillas y llaves.Nueve de cada diez errores son uno de esos tres.

La pantalla en blanco. A veces no sale ni error: la página queda vacía. Es que el servidor tiene los errores escondidos; así se configuran los servidores de verdad, para no enseñarle las tripas a los visitantes, y el error se anota en un archivo (el log). Cuando estés practicando, pon al principio del archivo:

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);

y los errores vuelven a aparecer en pantalla. En israelrivas.org están escondidos: si un alumno llega a ver una pantalla en blanco, el error quedó anotado en el servidor y yo lo leo ahí.

Así se hace, paso a paso

Cazar tres errores en un programa

1  <?php
2  $precio = 50;
3  $cantidad = 3
4  $total = $precio * $cantida;
5  echo "Total: $total;
6  ?>

Paso 1 · Primer intento. Parse error: syntax error, unexpected variable "$total", expecting ";" on line 4. Miro la 4… y luego la 3: le falta el ;. Lo pongo.

Paso 2 · Segundo intento. Parse error: syntax error, unexpected end of file on line 7. ¿Fin del archivo? Algo quedó sin cerrar. Cuento comillas: en la línea 5 abre y no cierra. Pongo la comilla: echo "Total: $total";

Paso 3 · Tercer intento. Ya corre, pero sale «Total: 0» y Warning: Undefined variable $cantida in line 4. Escribí cantida sin la d. Corrijo.

Sale:
Total: 150

Tres errores, tres mensajes, uno a la vez. Nunca cambies dos cosas sin probar en medio.

Cuidado con esto

Arreglar solo la línea que dice el mensaje. El ; que falta casi siempre está en la de arriba.

Cambiar cosas al azar. Lee, piensa qué significa, cambia una sola cosa, prueba. Si cambias tres, no sabrás cuál arregló (o cuál rompió).

Dejar los echo de prueba. Cuando el error ya se fue, quítalos; si no, tu página dice «aquí total = 150» en medio de todo.

Ejercicios

  1. ¿Qué error da?
    echo "Hola;
    ver la respuesta
    Parse error: comilla sin cerrar (syntax error, unexpected end of file). PHP busca la comilla de cierre hasta el final del archivo.
    Cómo se llega
    1. Abre comilla y nunca cierra.
    2. Todo lo que sigue lo toma como texto.
  2. ¿Qué error da?
    $x = 10;
    $y = 0;
    echo $x / $y;
    ver la respuesta
    Fatal error: Division by zero. Dividir entre 0 no se puede.
    Cómo se llega
    1. $y vale 0.
    2. Revisa el divisor antes: if ($y != 0).
  3. ¿Cuál línea está mal?
    1  $a = 4;
    2  $b = 5;
    3  echo $a + $B;
    ver la respuesta
    La línea 3: $B con mayúscula es otra variable, que no existe. Warning: Undefined variable $B.
    Cómo se llega
    1. PHP distingue mayúsculas en las variables.
    2. Es $b.
  4. El mensaje dice: Parse error: syntax error, unexpected token "echo", expecting ";" in tienda.php on line 8. ¿Dónde buscas primero?
    ver la respuesta
    En la línea 7: le falta el ; al final. (El echo de la línea 8 es donde PHP se dio cuenta.)
    Cómo se llega
    1. «expecting ;»: esperaba un punto y coma.
    2. Lo esperaba antes del echo, o sea al final de la línea anterior.
  5. Corrige el error:
    function saludo($n) {
        return "Hola $n";
    echo saludo("Ana");
    ver la respuesta
    Falta la llave de cierre de la función, antes del echo: }. Mensaje: Unclosed '{'.
    Cómo se llega
    1. Abre { en la línea 1 y nunca cierra.
    2. Cada { necesita su }.
  6. Subiste tu página y sale completamente en blanco, sin mensaje. ¿Qué haces?
    ver la respuesta
    Activar los errores mientras pruebo: ini_set('display_errors', 1); error_reporting(E_ALL); al principio del archivo (o leer el log del servidor).
    Cómo se llega
    1. Blanco sin mensaje = error escondido.
    2. Con display_errors aparece el mensaje con su línea.

El examen de php: la página que piensa

Diez preguntas de todas las lecciones, del mismo nivel que los ejercicios. Hay cuatro versiones parecidas: si no te va bien, lo repites con otra. Se aprueba con 7 de 10.

Puedes hacerlo sin entrar, pero si entras con tu nombre el resultado se guarda en tu tablero.

Hacer el examen →
← Antes: HTML y CSS: tu primera páginaSigue: Bases de datos y SQL →