include 'header.php'; ejecuta el código de otro archivo PHP en ese punto del script, como si estuviera pegado ahí. require 'header.php'; hace lo mismo, pero si el archivo no se puede cargar, require detiene el script con un error fatal mientras que include solo imprime un warning y continúa. El primer uso habitual es una cabecera y un pie de página compartidos por todas las páginas.
El bloque escribe primero header.php y footer.php, para que haya archivos que incluir. Ejecútalo y mira la pestaña Página:
Los archivos incluidos son archivos PHP normales: pueden contener HTML con etiquetas <?= ?>, y ven la variable $title asignada antes del require. Cambia el título y vuelve a ejecutarlo; todas las páginas que incluyen la cabecera recogerían un cambio hecho en ese único archivo.
include vs require
La única diferencia es lo que pasa cuando el archivo falta o no se puede leer. include imprime dos warnings, se evalúa como false y el script continúa:
Warning: include(sidebar.php): Failed to open stream: No such file or directory in /home/index.php on line 2
Warning: include(): Failed opening 'sidebar.php' for inclusion (include_path='.:/usr/share/php83') in /home/index.php on line 2
require imprime el mismo warning y luego lanza un Error, que termina el script salvo que algo lo capture:
PHP Warning: require(config.php): Failed to open stream: No such file or directory in /home/index.php on line 2
PHP Fatal error: Uncaught Error: Failed opening required 'config.php' (include_path='.:/usr/share/php83') in /home/index.php:2
Así que usa require para todo aquello sin lo que la página no puede ejecutarse (configuración, librerías de funciones, archivos de clases) e include para las partes opcionales. Para una parte que legítimamente puede no estar, compruébala antes en lugar de depender del warning:
Salida:
Spring sale: 20% off
banner.php included, include returned int(1)
sidebar.php not found, skipped
include_once y require_once
Un archivo que define una función o una clase solo se puede cargar una vez: cargarlo una segunda vez es un error fatal, porque la función ya existe.
Fatal error: Cannot redeclare greet() (previously declared in /home/helpers.php:2) in /home/helpers.php on line 2
Eso ocurre en cuanto dos archivos hacen cada uno require 'helpers.php'. require_once e include_once recuerdan qué archivos ya se cargaron y se los saltan la segunda vez, devolviendo true:
Salida:
int(1)
bool(true)
bool(true)
Hello, Ada
Usa las formas _once para archivos que declaran cosas, e include a secas para plantillas que quieres imprimir más de una vez. En los proyectos que usan Composer, el autoloader carga por ti los archivos de clases, así que las llamadas a require_once para clases casi desaparecen; consulta Composer.
Devolver un valor desde un archivo incluido
Un return en el nivel superior de un archivo incluido detiene ese archivo y devuelve un valor a la expresión include o require. Eso da un archivo de configuración limpio: sin variables globales, solo un valor que asignas al nombre que quieras.
Salida:
My Shop
shop
bool(false)
Los archivos de configuración de Laravel (config/app.php, config/database.php y los demás) funcionan así.
Variables y ámbito en los archivos incluidos
El código incluido se ejecuta en el ámbito de la línea que lo incluye. Al principio de un script ve todas las variables globales; dentro de una función solo ve las variables locales de esa función. Esa segunda regla es la base de un renderizador de plantillas mínimo: una función cuyas variables locales son exactamente las que debe ver la plantilla.
La pestaña Página muestra las dos listas, renderizadas a partir de un único archivo de plantilla. Como include se ejecuta dentro de render(), la plantilla ve $heading y $products pero no $secret. La forma foreach ... endforeach que usa la plantilla es la sintaxis alternativa que ofrece PHP para las plantillas HTML.
Rutas de include y DIR
Una ruta como 'helper.php' no se resuelve en relación con el archivo que contiene el include. PHP busca en el ajuste include_path (que normalmente empieza por ., el directorio de trabajo actual) y solo después en la propia carpeta del archivo que incluye. Así, dentro de partials/nav.php, include 'helper.php' puede cargar un helper.php completamente distinto de la raíz del proyecto. __DIR__, el directorio del archivo actual, elimina las dudas:
Salida:
loaded the root helper.php
loaded partials/helper.php
__DIR__ in nav.php is partials
Escribe cada include como __DIR__ . '/relative/path.php'. El directorio de trabajo depende de cómo se arrancó el script (el servidor web, una tarea cron, la línea de comandos desde otra carpeta), pero __DIR__ nunca cambia.
Nunca incluyas un archivo nombrado por el usuario
Un primer router habitual lee el nombre de la página de la URL: include $_GET['page'] . '.php';. Eso permite a un visitante elegir qué archivo del servidor se ejecuta, por ejemplo ?page=../../config (inclusión de archivos locales), y con configuraciones antiguas incluso un archivo de otro servidor. Asigna en su lugar los nombres permitidos a archivos. Ejecuta el bloque y haz clic en los enlaces: cada clic vuelve a ejecutar el script con un $_GET['page'] distinto.
Solo los tres nombres de $pages pueden llegar a require; el enlace ../secret recibe la página "Not found". Cómo leer de forma segura los valores de la petición se explica en _POST.
Preguntas frecuentes
¿Cuál es la diferencia entre include y require en PHP?
Los dos cargan y ejecutan otro archivo PHP. Si el archivo no se puede cargar, require detiene el script con un error fatal, mientras que include imprime un warning, devuelve false y deja que el script continúe. Usa require para los archivos sin los que la página no puede funcionar, como la configuración y las librerías de funciones.
¿Cuándo uso require_once en lugar de require?
Usa require_once para archivos que definen funciones, clases o constantes. Cargar un archivo así dos veces es un error fatal (Cannot redeclare), y require_once se salta el archivo si ya se cargó. Las plantillas que quieres imprimir varias veces usan include a secas.
¿Un archivo PHP incluido puede devolver un valor?
Sí. Un return en el nivel superior del archivo incluido lo termina y se convierte en el valor de la expresión include o require: $config = require 'config.php'; con return ['debug' => true]; en config.php. Sin return, include se evalúa como 1.
¿Un archivo incluido tiene acceso a mis variables?
Sí. El código incluido se ejecuta en el ámbito de la línea que lo incluye: al principio de un script ve las variables globales, y dentro de una función ve las variables locales de esa función y nada más. Las variables que crea quedan en ese mismo ámbito.
¿Escribo include('file.php') o include 'file.php'?
Las dos funcionan, porque include y require son construcciones del lenguaje, no funciones; los paréntesis solo envuelven la ruta. La mayoría de las guías de estilo escriben require 'file.php'; sin ellos.