include 'header.php'; esegue il codice di un altro file PHP in quel punto dello script, come se fosse incollato lì. require 'header.php'; fa lo stesso, ma se il file non si può caricare require ferma lo script con un errore fatale mentre include stampa solo un warning e prosegue. Il primo uso abituale è un header e un footer condivisi da tutte le pagine.
Il blocco scrive prima header.php e footer.php, così ci sono dei file da includere. Eseguilo e guarda la scheda Page:
I file inclusi sono normali file PHP: possono contenere HTML con i tag <?= ?>, e vedono la variabile $title impostata prima del require. Cambia il titolo ed eseguilo di nuovo; ogni pagina che include l'header recepirebbe una modifica a quell'unico file.
include vs require
L'unica differenza è cosa succede quando il file manca o non è leggibile. include stampa due warning, vale false e lo script prosegue:
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 stampa lo stesso warning e poi lancia un Error, che termina lo script a meno che qualcosa non lo catturi:
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
Quindi usa require per tutto ciò senza cui la pagina non può girare (configurazione, librerie di funzioni, file di classi) e include per le parti facoltative. Per una parte che può legittimamente mancare, verificala prima invece di affidarti al warning:
Output:
Spring sale: 20% off
banner.php included, include returned int(1)
sidebar.php not found, skipped
include_once e require_once
Un file che definisce una funzione o una classe si può caricare una volta sola: caricarlo una seconda volta è un errore fatale, perché la funzione esiste già.
Fatal error: Cannot redeclare greet() (previously declared in /home/helpers.php:2) in /home/helpers.php on line 2
Succede appena due file fanno ciascuno require 'helpers.php'. require_once e include_once ricordano quali file sono già stati caricati e li saltano la seconda volta, restituendo true:
Output:
int(1)
bool(true)
bool(true)
Hello, Ada
Usa le forme _once per i file che dichiarano qualcosa, e il semplice include per i template che vuoi stampare più di una volta. Nei progetti che usano Composer, l'autoloader carica i file delle classi per te, quindi le chiamate require_once per le classi in gran parte spariscono; vedi Composer.
Restituire un valore da un file incluso
Un return al livello principale di un file incluso ferma quel file e restituisce un valore all'espressione include o require. Ne viene fuori un file di configurazione pulito: nessuna variabile globale, solo un valore che assegni al nome che preferisci.
Output:
My Shop
shop
bool(false)
I file di configurazione di Laravel (config/app.php, config/database.php e gli altri) funzionano così.
Variabili e scope nei file inclusi
Il codice incluso viene eseguito nello scope della riga che lo include. In cima a uno script vede ogni variabile globale; dentro una funzione vede solo le variabili locali di quella funzione. Questa seconda regola è il modo in cui funziona un piccolo renderer di template: una funzione le cui variabili locali sono esattamente quelle che il template deve vedere.
La scheda Page mostra entrambe le liste, prodotte da un solo file di template. Dato che include viene eseguito dentro render(), il template vede $heading e $products ma non $secret. La forma foreach ... endforeach usata nel template è la sintassi alternativa che PHP offre per i template HTML.
Percorsi degli include e DIR
Un percorso come 'helper.php' non viene risolto rispetto al file che contiene l'include. PHP cerca nell'impostazione include_path (che normalmente inizia con ., la cartella di lavoro corrente) e solo dopo nella cartella del file che include. Quindi dentro partials/nav.php, include 'helper.php' può caricare un helper.php completamente diverso dalla radice del progetto. __DIR__, la cartella del file corrente, elimina l'incertezza:
Output:
loaded the root helper.php
loaded partials/helper.php
__DIR__ in nav.php is partials
Scrivi ogni include come __DIR__ . '/relative/path.php'. La cartella di lavoro dipende da come è stato avviato lo script (il server web, un cron job, la riga di comando da un'altra cartella), ma __DIR__ non cambia mai.
Non includere mai un file scelto dall'utente
Un classico primo router legge il nome della pagina dall'URL: include $_GET['page'] . '.php';. Questo permette a un visitatore di scegliere quale file del server viene eseguito, per esempio ?page=../../config (local file inclusion), e con vecchie impostazioni persino un file da un altro server. Associa invece i nomi consentiti ai file. Esegui il blocco e clicca i link: ogni clic esegue di nuovo lo script con un diverso $_GET['page'].
Solo i tre nomi in $pages possono arrivare a require; il link ../secret riceve la pagina "Not found". Leggere in modo sicuro i valori della richiesta è trattato in _POST.
Domande frequenti
Qual è la differenza tra include e require in PHP?
Entrambi caricano ed eseguono un altro file PHP. Se il file non si può caricare, require ferma lo script con un errore fatale, mentre include stampa un warning, restituisce false e lascia proseguire lo script. Usa require per i file senza cui la pagina non può funzionare, come la configurazione e le librerie di funzioni.
Quando usare require_once invece di require?
Usa require_once per i file che definiscono funzioni, classi o costanti. Caricare un file del genere due volte è un errore fatale (Cannot redeclare), e require_once salta il file se è già stato caricato. I template che vuoi stampare più volte usano il semplice include.
Un file PHP incluso può restituire un valore?
Sì. Un return al livello principale del file incluso lo termina e diventa il valore dell'espressione include o require: $config = require 'config.php'; con return ['debug' => true]; in config.php. Senza un return, include vale 1.
Un file incluso ha accesso alle mie variabili?
Sì. Il codice incluso viene eseguito nello scope della riga che lo include: in cima a uno script vede le variabili globali, e dentro una funzione vede le variabili locali di quella funzione e nient'altro. Le variabili che crea finiscono nello stesso scope.
Devo scrivere include('file.php') o include 'file.php'?
Funzionano entrambi, perché include e require sono costrutti del linguaggio, non funzioni; le parentesi racchiudono solo il percorso. La maggior parte delle guide di stile scrive require 'file.php'; senza.