Lab 03 — Arrays y bucles foreach en PHP¶
| Campo | Valor |
|---|---|
| Módulo | Implantación de Aplicaciones Web (IMW) |
| Ciclo | Administración de Sistemas Informáticos en Red (ASIR) |
| Unidad | UT4 — PHP en servidor |
| Criterios de evaluación (CE) | d (estructuras de control: foreach) |
| Requisitos | Labs 01 y 02 completados |
| Agrupación | Individual |
| Herramientas | Navegador + editor de texto + terminal |
| Apuntes | https://ichigar.codeberg.page/imw/recursos/ut4_php_03_arrays_y_listas/ |
| Tiempo estimado | 90–120 minutos |
Antes de empezar¶
Qué vamos a hacer
Los arrays en PHP son colecciones de valores. Son el tipo de dato más usado en una aplicación web: listas de incidencias, opciones de un formulario, resultados de una búsqueda… todo pasa por arrays.
En este lab practicarás los tres tipos principales de arrays y cómo recorrerlos con foreach:
- Arrays indexados — listas de valores con índice numérico (0, 1, 2…).
- Arrays asociativos — pares clave/valor, como los diccionarios o los objetos JSON.
- Arrays de arrays — listas de registros (una lista de incidencias, por ejemplo).
Al terminar tendrás un fichero listado.php con una tabla HTML generada a partir de un array de 5 incidencias. Es la base directa de los labs 04 (condicionales) y 08 (persistencia en JSON).
Antes de empezar: comprueba que gestor.local sigue funcionando
Desde el navegador de tu Windows, visita http://gestor.local. Debes ver la página del Lab 01 (tu index.php personalizado).
Si el navegador dice "no se puede resolver el nombre" o similar, es que ha pasado tiempo desde los labs anteriores y algo se ha desconfigurado. Causas habituales:
- La IP del servidor ha cambiado (DHCP): ejecuta
ip a | grep "inet "en la VM para ver la IP actual y editaC:\Windows\System32\drivers\etc\hostsen tu Windows (como administrador) para ajustar la línea degestor.local. - Apache no está arrancado: en el servidor,
sudo systemctl start apache2.
Hasta que http://gestor.local no responda, no sigas con este lab.
Cómo se entrega este lab¶
ZIP con esta estructura exacta:
apellido_nombre_lab03/
├── gestor/
│ └── public/
│ ├── arrays.php
│ ├── listado.php
│ └── catalogo.php
├── capturas/
│ ├── paso1_lista_simple.png
│ ├── paso2_incidencia_asociativa.png
│ ├── paso3_tabla_incidencias.png
│ └── paso5_catalogo.png
└── RESPUESTAS.md
Nombres prescritos
Los nombres de ficheros y carpetas son obligatorios y exactos. El script de corrección busca estos nombres concretos.
Cómo preparar el ZIP (Windows o Linux/macOS):
- Crea la carpeta
apellido_nombre_lab03/(minúsculas, sin espacios ni acentos) y reproduce la estructura: los 3 ficheros PHP los crearás en el servidor durante los pasos del lab y debes copiarlos a tu carpeta de entrega antes de hacer el ZIP; guarda también las 4 capturas con el nombre exacto, y creaRESPUESTAS.md. - Comprime:
- Windows: clic derecho sobre la carpeta → Enviar a → Carpeta comprimida (en zip).
- Linux/macOS:
zip -r apellido_nombre_lab03.zip apellido_nombre_lab03/.
- Verifica que al abrir el ZIP aparece una sola carpeta raíz
apellido_nombre_lab03/.
Paso 1 — Arrays indexados y foreach¶
Conceptos
- Un array indexado es una lista de valores con índice numérico. El primer elemento está en la posición
0. - Se crea con corchetes:
$arr = ['baja', 'media', 'alta'];. - Se añade al final con
$arr[] = 'critica';. Los corchetes vacíos no son un error: significan "el siguiente índice libre", y PHP lo asigna automáticamente. - Se cuenta el número de elementos con
count($arr). foreachrecorre todos los elementos uno a uno.- Sintaxis
foreach (...): ... endforeach: dentro de bloques HTML usamos esta forma en lugar de las llaves{ ... }. Es más legible cuando se mezclan PHP y HTML porque la etiqueta de cierre dice claramente qué bloque se cierra. Cadaforeachnecesita suendforeach: si te lo saltas, PHP intenta interpretar el resto del fichero como parte del bucle y la página deja de funcionar.
Objetivo. Crear un array con varias prioridades y mostrarlas como una lista HTML <ul>.
Tarea. Crea ~/gestor/public/arrays.php:
Visita http://gestor.local/arrays.php. Debes ver una lista con 4 prioridades.
Pista si no aparece nada
Comprueba que cada foreach tiene su endforeach al final. Si te saltas uno, la página entera deja de funcionar.
Responde en RESPUESTAS.md, sección ## Paso 1.
Añade una quinta prioridad al array (
'urgente'por ejemplo) y recarga. ¿Cuántos elementos aparecen ahora? ¿Qué valor tienecount($prioridades)?
Captura requerida. Después de añadir la 5ª prioridad del ejercicio anterior, guarda en capturas/paso1_lista_simple.png una captura con la lista visible. Debe verse:
- La URL
http://gestor.local/arrays.php. - La línea "Total: 5 niveles."
- La lista
<ul>con los 5 elementos (baja,media,alta,critica,urgente).
Verificación.
-
~/gestor/public/arrays.phpexiste y carga en el navegador. - La lista muestra las 5 prioridades (tras añadir la 5ª en el ejercicio).
- He guardado
capturas/paso1_lista_simple.pngcon los 5 elementos.
Paso 2 — Arrays asociativos¶
Conceptos
- Un array asociativo se diferencia del indexado del Paso 1 en que las claves son texto en lugar de números. En el Paso 1 accedías con
$prioridades[0](índice numérico); aquí accederás con$incidencia['titulo'](clave de texto). La notación es la misma, lo que cambia es el contenido entre corchetes. - Se crea con la sintaxis
'clave' => valor. El símbolo=>se lee como "apunta a":'titulo' => 'Impresora'se lee "la clave titulo apunta al valor Impresora". - Las claves distinguen mayúsculas:
$inc['titulo']y$inc['Titulo']son claves distintas. - Es el equivalente PHP de un diccionario en Python o un objeto JSON. Lo usaremos para representar cada incidencia en el proyecto: un array con claves
id,titulo,descripcion,prioridad,estado, etc.
Objetivo. Ampliar arrays.php para mostrar los datos de una única incidencia representada como array asociativo.
Tarea. Modifica ~/gestor/public/arrays.php. Dentro del bloque PHP que ya tienes, justo después de la línea $prioridades[] = 'critica'; y antes del ?>, añade:
Al final del <body>, justo antes de la etiqueta </body> de cierre (debe quedar después del <ul> de prioridades del Paso 1), añade este bloque:
Guarda y recarga.
Pista
Si te equivocas en una clave (ej. $incidencia['titulos'] en plural), PHP muestra un aviso "Undefined array key" si tienes display_errors activo. Si no ves el aviso y en su lugar la página sale en blanco o con HTTP ERROR 500, lo más probable es que display_errors siga apagado en php.ini: vuelve al Paso 5 del lab A1 — Depuración: ver los errores de PHP — y actívalo. Una vez hecho, no tendrás que volver a tocarlo en los próximos labs.
Responde en RESPUESTAS.md, sección ## Paso 2.
¿Qué diferencia fundamental hay entre un array indexado (el del Paso 1) y un array asociativo (el del Paso 2)? Cita un escenario práctico para cada uno. (Piensa: ¿cuándo te interesa acceder por posición como
$arr[0]y cuándo por nombre como$arr['titulo']? ¿Qué tipo usarías para una lista simple de prioridades y cuál para los datos de una persona?)
Captura requerida. Guarda en capturas/paso2_incidencia_asociativa.png una captura con la ficha visible. Debe verse:
- La URL
http://gestor.local/arrays.php. - La sección "Ficha de la incidencia" con los 5 campos (ID, Título, Descripción, Prioridad, Estado).
Verificación.
-
arrays.phptiene el array asociativo$incidenciacon al menos 5 claves. - La ficha aparece debajo de la lista del Paso 1.
- He guardado
capturas/paso2_incidencia_asociativa.png.
Paso 3 — Array de arrays: lista de incidencias en una tabla¶
Conceptos
- En aplicaciones reales, normalmente tienes muchos registros del mismo tipo: una lista de incidencias, una lista de usuarios, una lista de pedidos. Se representan como arrays de arrays asociativos.
- Se recorren con
foreach, y dentro del bucle accedes a cada campo con la notación$elemento['clave']. - Variable de iteración: en
foreach ($incidencias as $inc):, la variable$inctoma el valor de cada elemento en cada vuelta del bucle. Dentro del bucle,$increpresenta la incidencia "actual" (un array asociativo), y accedes a sus claves con$inc['id'],$inc['titulo'], etc. Después delendforeach,$incya no se usa. El nombre$inces solo una elección — podríamos haberla llamado$xo$item, pero conviene un nombre que indique qué representa. - La estructura HTML natural para presentarlos es una tabla
<table>.
Objetivo. Crear un fichero nuevo listado.php con una lista de al menos 5 incidencias y mostrarlas en una tabla HTML.
Tarea. Crea ~/gestor/public/listado.php:
Visita http://gestor.local/listado.php. Debes ver una tabla con las 5 filas.
El bloque <style> es opcional
El <style> con CSS dentro del <head> se incluye solo para que la tabla sea legible (bordes, padding, fondo de cabecera). Es un detalle estético: si lo quitas, la tabla sigue siendo válida. Los siguientes ficheros del lab no requieren CSS.
Pista sobre el foreach dentro de la tabla
Observa dónde están el <?php foreach ...: ?> y el <?php endforeach ?>: fuera de <tr> y </tr>. Es decir, por cada iteración del bucle se genera un <tr> completo. Un error habitual es meter el foreach dentro del <tr> y generar tablas rotas.
Responde en RESPUESTAS.md, sección ## Paso 3.
Añade una 6ª incidencia al array
$incidenciasy recarga. ¿Has tenido que tocar el bloque delforeachpara que aparezca la nueva fila? ¿Por qué?
La 6ª incidencia es solo para responder a la pregunta. Puedes dejarla en el array o quitarla — el requisito mínimo de entrega son 5 incidencias.
Captura requerida. Guarda en capturas/paso3_tabla_incidencias.png una captura con la tabla visible. Debe verse:
- La URL
http://gestor.local/listado.php. - La cabecera con "Total: N incidencias."
- La tabla con sus 4 columnas y todas las filas.
Verificación.
-
~/gestor/public/listado.phpexiste y carga. - El array
$incidenciastiene al menos 5 elementos. - La tabla muestra correctamente todas las filas.
- He guardado
capturas/paso3_tabla_incidencias.png.
Paso 4 — Guardar el total en una variable reutilizable¶
Conceptos
- Guardar un valor en una variable reutilizable hace el código más claro y mantenible. En el Paso 3 llamabas a
count($incidencias)directamente dentro del HTML; en aplicaciones reales es habitual reutilizar el total en varios sitios (cabecera, pie, mensaje "X de Y elementos"...). Si el cálculo cambia mañana — por ejemplo, contar solo las abiertas — solo tocas una línea. - Esta refactorización es además la forma natural de tener el total disponible para los condicionales del Lab 04: allí decidiremos qué pintar según si hay incidencias o no.
Objetivo. Ampliar listado.php para guardar el total en una variable reutilizable.
Tarea 1 — Declarar $total_incidencias. Modifica ~/gestor/public/listado.php. Añade al bloque PHP inicial, después del array $incidencias:
Tarea 2 — Usar la variable en el contador. En el HTML, cambia la línea del Paso 3 que tenía:
por esta otra que usa la variable ya calculada:
Guarda y recarga http://gestor.local/listado.php. La página se ve exactamente igual que en el Paso 3: el cambio es interno, no visual. Por eso este paso no requiere captura nueva.
Responde en RESPUESTAS.md, sección ## Paso 4.
¿Qué ventaja tiene guardar el total en
$total_incidenciasfrente a escribircount($incidencias)cada vez que necesites el número? Piensa en el escenario de tener que mostrar el total en dos sitios distintos de la página, o en cómo afectaría a tu código si mañana cambiaras el criterio (contar solo abiertas, por ejemplo).
Verificación.
-
listado.phpdeclara la variable$total_incidencias = count($incidencias)en el bloque PHP inicial. - El
<p>Total:</p>del Paso 3 usa ahora$total_incidenciasen lugar decount()inline. -
listado.phppasaphp -lsin errores.
Paso 5 — Aplica lo aprendido: catálogo de equipos del taller¶
Qué es este paso
Los cuatro pasos anteriores han sido guiados: te he dado el código y tú lo has tecleado, probado y respondido. En este quinto paso no hay código de referencia. Lo que hay son requisitos, y tú aplicas lo aprendido en los pasos 1 a 4 para cumplirlos.
Vas a aplicar exactamente el mismo patrón que en los Pasos 2, 3 y 4, pero con un contexto distinto: en lugar de incidencias, equipos de un taller de reparaciones. Los tipos de array, la tabla HTML, el foreach, count() y htmlspecialchars() funcionan igual — solo cambian los nombres de las variables y los campos.
Objetivo. Crear un fichero nuevo catalogo.php que muestre una ficha del taller y una tabla con sus equipos, aplicando todo lo visto en los pasos 1 a 4.
Tarea. Crea ~/gestor/public/catalogo.php cumpliendo los requisitos siguientes.
Requisitos obligatorios de contenido:
- Un array asociativo
$tallercon al menos 3 campos de texto:nombre(por ejemplo'Reparaciones Chema').ciudad(por ejemplo'Las Palmas').responsable(tu nombre, o uno inventado).
- Un array de arrays
$equiposcon al menos 6 equipos, cada uno con 4 claves:id('eq001','eq002'…).modelo(por ejemplo'Lenovo ThinkPad T480').ubicacion(por ejemplo'Banco 2','Almacén').estado(uno de estos cuatro valores:'operativo','averiado','en_reparacion','retirado').
- Una variable calculada:
$total_equipos→ guarda el número total de equipos usandocount($equipos)(como en el Paso 4 con$total_incidencias).
Requisitos de presentación HTML:
- Crea una variable
$titulocon el texto"Catálogo de equipos de [nombre del taller]", construida con concatenación o interpolación a partir de$taller['nombre'](como viste en el Lab 02 Paso 4), y muéstrala en un<h1>usando<?= htmlspecialchars($titulo) ?>. - Una ficha del taller con
<ul>(como en el Paso 2 de este lab) mostrando los 3 campos del array asociativo. - Un
<h2>con el texto"Total: N equipos", dondeNes la variable$total_equipos. - Una tabla
<table>con los equipos, con al menos las columnas ID, Modelo, Ubicación, Estado. Recórrela conforeachcomo en el Paso 3.
Requisitos de calidad del código:
error_reporting(E_ALL)yini_set('display_errors', '1')al principio del fichero.- Al menos 2 comentarios: uno sobre cada uno de los dos arrays (qué representan y qué datos contienen).
htmlspecialchars()en todos los valores de texto que muestres en el HTML.
Visita http://gestor.local/catalogo.php para comprobar el resultado.
Pista sobre la concatenación del <h1>
Puedes usar interpolación con comillas dobles (la v2 del Lab 02 Paso 4):
O el operador punto:
Ambas valen. Elige la que te resulte más cómoda.
Responde en RESPUESTAS.md, sección ## Paso 5.
- ¿Qué diferencias hay entre tu
$tallery tu$equipos? Indica de qué tipo es cada uno (indexado, asociativo, array de arrays) y por qué has elegido ese tipo para cada caso.- Imagina que quisieras calcular cuántos equipos están en estado
'operativo'. Sin escribir el código, describe en un par de frases qué necesitarías para hacerlo: ¿te sirve lo que ya sabes deforeach, o te faltaría alguna herramienta nueva?
Captura requerida. Guarda en capturas/paso5_catalogo.png una captura del navegador visitando http://gestor.local/catalogo.php. Debe verse:
- La URL
http://gestor.local/catalogo.php. - El
<h1>con el título construido por concatenación. - La ficha del taller con los 3 campos.
- El
<h2>con el total de equipos. - La tabla con al menos 6 equipos y sus 4 columnas.
Verificación.
-
~/gestor/public/catalogo.phpexiste y carga en el navegador. - Tiene un array asociativo
$tallercon al menos 3 campos. - Tiene un array de arrays
$equiposcon al menos 6 equipos. - Hay una variable
$tituloconstruida con concatenación o interpolación a partir de$taller['nombre']. - La variable
$total_equiposse calcula concount($equipos)(no es un número hardcoded como$total_equipos = 6;). - La página muestra la ficha del taller, el total de equipos y la tabla.
- Todos los valores de texto se muestran con
htmlspecialchars(). - He guardado
capturas/paso5_catalogo.png.
Ampliación opcional¶
Para alumnos que terminen pronto
Prueba a:
- Añadir una columna "Nº" en la tabla con el número de fila (1, 2, 3…). Pista:
foreach ($incidencias as $i => $inc)te da tanto el índice$icomo el valor$inc. - Recorrer las claves y valores de
$incidenciadel Paso 2 conforeach ($incidencia as $clave => $valor)y generar una tabla de 2 columnas (clave / valor) automáticamente, sin listar los campos uno a uno.
Estas ampliaciones no se corrigen.
Checklist final de entrega¶
Antes de subir el ZIP al Campus:
- He creado la carpeta
apellido_nombre_lab03/con mi apellido y nombre reales. - Dentro hay
gestor/public/arrays.php,listado.phpycatalogo.php. - Dentro hay
capturas/con los 4 PNG (paso1_lista_simple.png,paso2_incidencia_asociativa.png,paso3_tabla_incidencias.png,paso5_catalogo.png). - Dentro hay
RESPUESTAS.mdcon las 5 secciones (## Paso 1a## Paso 5) rellenas. - Los 3 ficheros PHP pasan
php -lsin errores. - El ZIP se llama
apellido_nombre_lab03.zipy al descomprimir aparece una sola carpeta raíz. - He subido el ZIP al Campus antes de la fecha límite.
Anexo — Plantilla de RESPUESTAS.md¶
Crea RESPUESTAS.md dentro de apellido_nombre_lab03/:
# Respuestas — Lab 03 Arrays y foreach
**Nombre:** Apellido, Nombre
**Fecha:** YYYY-MM-DD
## Paso 1
(Tu respuesta: qué pasa al añadir una 5ª prioridad y valor de `count($prioridades)`.)
## Paso 2
(Tu respuesta: diferencia entre array indexado y asociativo, y un escenario práctico de cada uno.)
## Paso 3
(Tu respuesta: ¿has tocado el `foreach` al añadir la 6ª incidencia? ¿Por qué?)
## Paso 4
(Tu respuesta: ventaja de guardar el total en `$total_incidencias` frente a escribir `count($incidencias)` cada vez. Piensa en mostrar el total en dos sitios y en el escenario de cambiar mañana el criterio de cálculo.)
## Paso 5
1. (Tu respuesta: diferencias entre `$taller` y `$equipos`, tipo de cada uno y por qué.)
2. (Tu respuesta: descripción informal de qué necesitarías para contar equipos operativos y si las herramientas de este lab te bastan o no.)