En la Unidad 1 quedó pendiente una pregunta: ¿y si tengo diez páginas?
Copiar la navbar diez veces obliga a hacer cada cambio diez veces. Con include, la
navbar se escribe en un archivo y cada vista la trae con una línea.
Cómo funciona
include "archivo.php"; hace exactamente lo que dice: pega el contenido de ese
archivo en ese lugar, y PHP lo ejecuta como si siempre hubiera estado ahí.
Una vista armada con partes
flowchart LR
subgraph V["index.php"]
A["include cabecera.php"]
B["contenido propio<br/>de la portada"]
C["include pie.php"]
end
H["partes/cabecera.php<br/>(head y navbar)"] -.-> A
P["partes/pie.php<br/>(footer)"] -.-> C
V --> R["HTML completo<br/>que recibe el navegador"]
Las tres vistas incluyen los mismos dos archivos. Cambiar un enlace de la navbar
es cambiar una línea en partes/cabecera.php.
Paso a paso
1. Las carpetas
El mini sitio con partes
mi-sitio/
|-- index.php <- vista: Inicio
|-- sobre-mi.php <- vista: Sobre mí
|-- contacto.php <- vista: Contacto
|-- datos.php <- arreglos con la información del sitio
|-- partes/
| |-- cabecera.php <- <!DOCTYPE>, <head>, Tailwind y la navbar
| `-- pie.php <- el <footer> y el cierre de </body></html>
`-- img/
2. La cabecera
Todo lo que se repite antes del contenido de cada vista:
Arriba, en PHP, cada enlace parte con la clase normal y solo el de la página actual
cambia a la clase activa. Abajo, el HTML solo imprime la clase que corresponde.
Las etiquetas quedan abiertas en un archivo y se cierran en otro
<body> y <main> se abren en la cabecera y se cierran en el pie. Por separado
se ven incompletos, pero PHP los junta antes de enviarlos: el navegador recibe el
documento completo.
4. Cada vista
<?php$titulo = "Inicio";$pagina = "inicio";include __DIR__ . "/partes/cabecera.php";?><h1 class="text-4xl font-bold text-gray-900">Bienvenido</h1><p class="mt-4">Este es el contenido propio de la portada.</p><?php include __DIR__ . "/partes/pie.php"; ?>
La vista solo tiene su contenido. Las variables $titulo y $pagina se crean
antes del include, y la cabecera las usa para el <title> y para marcar la página
activa.
El archivo incluido sí ve las variables
Un archivo incluido comparte las variables de quien lo incluye: es como si su
código estuviera escrito ahí mismo. Por eso la cabecera puede leer $pagina.
Incorrecto: definir las variables después del include
Warning: Undefined variable $titulo in /home/ana/mi-sitio/partes/cabecera.php on line 7
PHP lee de arriba hacia abajo: cuando ejecuta la cabecera, $titulo todavía no
existe. Fíjate en que el error dice cabecera.php, no index.php.
Rutas con __DIR__
__DIR__ es una constante que vale la carpeta del archivo donde está escrita.
__DIR__ . "/partes/pie.php" arma una ruta completa que no depende de desde dónde
se levantó el servidor.
Escribes
PHP busca el archivo
include "partes/pie.php";
En la carpeta desde donde se ejecuta el programa, y luego en la del archivo. Casi siempre funciona, hasta que las vistas están en subcarpetas
include __DIR__ . "/partes/pie.php";
Exactamente en partes/, junto al archivo que lo incluye. Siempre
Correcto: DIR en todos los include y require
Es una costumbre que no cuesta nada y evita la tarde perdida buscando por qué el
include funciona en index.php pero no en admin/listado.php. Y recuerda que
Linux distingue mayúsculas: Partes/Pie.php no es partes/pie.php.
include, require y _once
Instrucción
Si el archivo no existe
Si ya se incluyó antes
include
Warning y la página sigue
Lo vuelve a incluir
require
Fatal error y la página se detiene
Lo vuelve a incluir
include_once
Warning y sigue
No lo incluye de nuevo
require_once
Fatal error y se detiene
No lo incluye de nuevo
Correcto: la regla del curso
Partes visuales (cabecera, pie, una tarjeta repetida): include. Se pueden
incluir varias veces y, si falta una, el resto de la página se ve igual.
Archivos con datos (datos.php y, en la Unidad 3, conexion.php):
require_once. Sin ellos la página no puede funcionar, así que es mejor que se
detenga con un error claro.
Hoy los registros están escritos a mano en datos.php. En la Unidad 3, ese
archivo se reemplaza por una consulta a PostgreSQL que entrega un arreglo con la
misma forma, y las vistas no cambian.
Pruébalo
Crea partes/cabecera.php y partes/pie.php y úsalos en index.php
Inclúyelos también en las otras dos vistas y comprueba que las tres se ven iguales
Cambia el nombre de un enlace en la cabecera y mira que cambia en las tres vistas
Marca la página activa con $pagina y recorre las tres vistas
Error provocado: escribe mal el nombre del archivo en un include y luego en un require, y compara
Error provocado: define $titulo después del include y lee en qué archivo dice el error
Errores comunes
Síntoma
Causa
Solución
include(partes/pie.php): Failed to open stream: No such file or directory
Ruta o nombre mal escrito, o mayúsculas distintas
Usa __DIR__ y revisa el nombre con ls
Undefined variable $titulo in …/cabecera.php
La variable se definió después del include, o no se definió en esa vista
Define las variables antes del include, en todas las vistas
La navbar no marca ninguna página
El valor de $pagina no coincide con el que compara la cabecera
Mismo texto exacto en la vista y en la cabecera
Al abrir partes/cabecera.php en el navegador se ve una página rota
Las partes no son páginas: no se abren solas
Abre siempre la vista (index.php)
Checkpoint
Intenta responder antes de desplegar cada pregunta.
¿Qué diferencia hay entre include y require si el archivo no existe?
include da un Warning y la página sigue sin esa parte. require da un Fatal
error y la página se detiene ahí.
¿Por qué datos.php se incluye con require_once y la cabecera con include?
Porque sin los datos la página no puede funcionar: mejor que se detenga con un
error claro (require). Si falta la cabecera, el resto de la página igual se puede
ver (include).
La cabecera muestra Undefined variable $pagina. ¿Qué revisas en la vista?
Que $pagina se defina antes de la línea del include, y que esté escrita
igual.
¿Qué ventaja tiene __DIR__ . "/partes/pie.php" sobre "partes/pie.php"?
Que la ruta parte siempre desde la carpeta del archivo que hace el include, sin
depender de desde dónde se ejecuta el programa. Sigue funcionando cuando hay
vistas en subcarpetas.