Un registro es un arreglo asociativo. Varios registros juntos son un arreglo de arreglos: una lista donde cada elemento es, a su vez, un arreglo con claves. Tiene exactamente la forma de una tabla: cada elemento es una fila y cada clave es una columna.

Una lista de registros

<?php
$estudiantes = [
    ["id" => 1, "nombre" => "Ana Pérez", "carrera" => "Análisis de Sistemas", "promedio" => 5.8],
    ["id" => 2, "nombre" => "Benjamín Soto", "carrera" => "Electricidad", "promedio" => 4.2],
    ["id" => 3, "nombre" => "Camila Ruiz", "carrera" => "Análisis de Sistemas", "promedio" => 6.4],
];

La misma información, como arreglo y como tabla

                   "id"   "nombre"         "carrera"               "promedio"
                 +------+----------------+-----------------------+----------+
 $estudiantes[0] |  1   | Ana Pérez      | Análisis de Sistemas  |   5.8    |
                 +------+----------------+-----------------------+----------+
 $estudiantes[1] |  2   | Benjamín Soto  | Electricidad          |   4.2    |
                 +------+----------------+-----------------------+----------+
 $estudiantes[2] |  3   | Camila Ruiz    | Análisis de Sistemas  |   6.4    |
                 +------+----------------+-----------------------+----------+

 $estudiantes[1]["nombre"]  ->  "Benjamín Soto"
              ^     ^
              |     `-- columna: la clave del registro
              `-- fila: la posición en la lista

Para llegar a un dato se usan dos corchetes: primero la fila (posición) y después la columna (clave).

<?php
echo $estudiantes[0]["nombre"] . "\n";
echo $estudiantes[2]["promedio"] . "\n";
echo count($estudiantes) . " estudiantes\n";
Ana Pérez
6.4
3 estudiantes

Así van a llegar los datos de la base de datos

En la Unidad 3, cuando le pidas a PostgreSQL todas las filas de una tabla, PHP te las va a entregar con esta misma forma: un arreglo de arreglos asociativos, uno por fila, con el nombre de cada columna como clave. Todo lo que aprendas a hacer con este arreglo funcionará igual con los datos reales.

Recorrer: cada vuelta es un registro

<?php
foreach ($estudiantes as $estudiante) {
    echo $estudiante["nombre"] . " (" . $estudiante["promedio"] . ")\n";
}
Ana Pérez (5.8)
Benjamín Soto (4.2)
Camila Ruiz (6.4)

En cada vuelta, $estudiante (singular) es un arreglo asociativo: una fila completa. Por eso se accede con $estudiante["nombre"], con un solo corchete.

Incorrecto: dos corchetes dentro del foreach

<?php
foreach ($estudiantes as $estudiante) {
    echo $estudiante[0]["nombre"];
}
PHP Warning:  Undefined array key 0 in /home/ana/prueba.php on line 3

$estudiante ya es la fila. No tiene posición 0: tiene las claves "id", "nombre", "carrera" y "promedio".

Generar una tabla HTML

Esta es la razón de toda la parte: la tabla de la Unidad 1, ahora generada desde los datos.

<?php
$estudiantes = [
    ["id" => 1, "nombre" => "Ana Pérez", "carrera" => "Análisis de Sistemas", "promedio" => 5.8],
    ["id" => 2, "nombre" => "Benjamín Soto", "carrera" => "Electricidad", "promedio" => 3.6],
    ["id" => 3, "nombre" => "Camila Ruiz", "carrera" => "Análisis de Sistemas", "promedio" => 6.4],
];
?>
 
<table class="w-full border-collapse text-left">
  <caption class="mb-2 text-left font-bold">Estudiantes inscritos</caption>
  <thead class="bg-gray-100">
    <tr>
      <th class="border border-gray-300 px-3 py-2">Nombre</th>
      <th class="border border-gray-300 px-3 py-2">Carrera</th>
      <th class="border border-gray-300 px-3 py-2 text-right">Promedio</th>
    </tr>
  </thead>
  <tbody>
    <?php foreach ($estudiantes as $estudiante): ?>
      <?php
      $color = "";
      if ($estudiante["promedio"] < 4.0) {
          $color = "text-red-700";
      }
      ?>
      <tr>
        <td class="border border-gray-300 px-3 py-2"><?= $estudiante["nombre"] ?></td>
        <td class="border border-gray-300 px-3 py-2"><?= $estudiante["carrera"] ?></td>
        <td class="border border-gray-300 px-3 py-2 text-right <?= $color ?>">
          <?= number_format($estudiante["promedio"], 1, ",", ".") ?>
        </td>
      </tr>
    <?php endforeach; ?>
  </tbody>
</table>

El color del promedio se decide antes del <tr>, en un bloque PHP: si es rojo, $color vale "text-red-700"; si no, queda vacío. En el HTML solo se imprime. Es la misma idea de Ciclos que generan HTML: calcular arriba, imprimir abajo.

Qué parte escribe PHP

flowchart LR
    A["$estudiantes<br/>(3 registros)"] --> B["foreach"]
    B -->|"vuelta 1"| C["tr de Ana"]
    B -->|"vuelta 2"| D["tr de Benjamín"]
    B -->|"vuelta 3"| E["tr de Camila"]
    C --> F["tbody"]
    D --> F
    E --> F

El <thead> se escribe una vez, a mano. Solo el <tr> de los datos está dentro del foreach. Si mañana hay 40 estudiantes, el código no cambia.

Incorrecto: el thead dentro del foreach

Si <thead> y sus <th> quedan dentro del ciclo, la fila de encabezados se repite antes de cada estudiante. Lo único que va dentro del ciclo es lo que cambia por cada registro.

Correcto: mensaje cuando la lista está vacía

<?php if (count($estudiantes) === 0): ?>
  <p class="text-gray-600">Todavía no hay estudiantes inscritos.</p>
<?php else: ?>
  <table>…</table>
<?php endif; ?>

Una tabla con encabezados y sin filas parece un error. Un texto que explica que no hay datos, no.

Pruébalo

  • Crea un arreglo con cinco registros de algo que te guste (películas, juegos, libros) con al menos cuatro claves
  • Imprime el segundo campo del tercer registro
  • Genera una tabla HTML desde el arreglo en una página con php -S
  • Pinta en rojo una celda según una condición
  • Vacía el arreglo ([]) y comprueba que aparece el mensaje en vez de la tabla
  • Error provocado: usa $registro[0]["clave"] dentro del foreach y lee el Warning

Errores comunes

SíntomaCausaSolución
Undefined array key 0 dentro del foreachUsaste dos corchetes sobre el elemento, que ya es la fila$registro["clave"], con un solo corchete
Undefined array key "nombre" en una sola filaA ese registro le falta la clave, o está escrita distintoTodos los registros con las mismas claves
Los encabezados se repiten en cada filaEl <thead> quedó dentro del foreachSolo el <tr> de datos va dentro del ciclo

Checkpoint

Intenta responder antes de desplegar cada pregunta.