Le funzioni include e require in PHP

Le funzioni include e require sono molto semplici da capire ed usare, ma vale la pena concentrarci con qualche esempio per apprezzarne le grandi potenzialità nei siti web complessi.

Indice dell'articolo

Le funzioni include e require di PHP hanno uno scopo semplicissimo: includere ed integrare all'interno di uno script PHP altro codice esistente in altri script, per aggiungere funzionalità o semplificare la manutenzione. Ci sono almeno quattro funzionalità che dobbiamo tenere a mente. Vediamo quali.

Semplificare il layout del sito

Abbiamo spesso visto come con la struttura di un sito web sia fissata dall'inizio scegliendo come suddividere le diverse pagine tra intestazione' barra di navigazione, barra laterale, footer ad esempio con l'uso dei tag semantici. Queste sezioni sono spesso, se non sempre, ripetute interamente in tutte le pagine del sito web. Mettiamo caso vogliamo modificare il titolo del sito nell'header' o il nome di un menù nel nav, questa modifica dovrebbe essere ripetuta in tutte le pagine del sito facendoci perdere un sacco di tempo con la probabilità di perderci una o più pagine nel caso il sito sia davvero molto grande. Tanto vale allora scrivere a parte il codice di queste sezioni creando dei file/script specifici header.php, nav.php, footer.php, in cui inserire il codice delle rispettive sezioni, e richiamare all'interno di ogni pagina del nostro sito questi file per includerli. Un esempio di classica pagina HTML5 con la struttura a tag semantici che abbiamo comunque creato con file .php anche se non c'è, di fatto, codice lato server:

//index.php
<!DOCTYPE html>
<html lang="it">
	<head>
		<title>Esercizio</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link href="/css/style.css" rel="stylesheet" type="text/css">
	</head>
<body>
<header>
	<div id="logo"><img src="/img/logo.svg" alt="logo"></div>
	<div id="title">Pagina di prova</div> 
</header>
<nav>
	<a href="#">Home</a>
	<a href="#">Pagina 1</a>
	<a href="#">Pagina 2</a>
	<a href="#">Pagina 3</a>
</nav>
<aside>
    <h2>Pubblicità</h2>
    <img src="/img/vertical.jpg" alt="banner verticale">
</aside>
<main>
<h1>Titolo a caso</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</main>

<footer>Realizzato da Alfredo Centinaro</footer>
</body>	
</html>

Come si trasforma il file index.php con i nuovi file di supporto da includere

<!DOCTYPE html>
<html lang="it">
	<head>
		<title>Esercizio</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link href="/css/style.css" rel="stylesheet" type="text/css">
	</head>
<body>
<?php include("header.php") ?>
<?php include("nav.php") ?>
<?php include("aside.php") ?>
<main>
<h1>Titolo a caso</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</main>

<?php include("footer.php") ?>

</body>	
</html>

 Aggiungiamo i file

header.php

<header>
	<div id="logo"><img src="/img/logo.svg" alt="logo"></div>
	<div id="title">Pagina di prova</div> 
</header>

nav.php

<nav>
	<a href="#">Home</a>
	<a href="#">Pagina 1</a>
	<a href="#">Pagina 2</a>
	<a href="#">Pagina 3</a>
</nav>

aside.php

<aside>
    <h2>Pubblicità</h2>
    <img src="/img/vertical.jpg" alt="banner verticale">
</aside>

footer.php

<footer>Realizzato da Alfredo Centinaro</footer>

 

Quali controindicazioni ha questa tecnica? Se nel nostro sito ci sono pagine html semplici con estensione .html, bene queste non possono essere più utilizzate perché non saremmo capaci di utilizzarci sopra le funzioni di inclusione o codice php in generale. Poco male direi. Fateci caso: quanti siti usano ancora pagine html pure se non siti poco professionali e di modesta dimensione (eccezion fatta per alcuni CMS che usano strategie particolari)? La funzione include deve essere gestita dal nostro server essendo codice php e ovviamente può introdurre una piccola latenza direi decisamente molto trascurabile rispetto ai vantaggi. Certo, abbiamo una proliferazione di file, nel nostro caso con codice davvero esiguo per l'esempio fatto, ma immaginate quando all'interno va inserito molto codice js, css in linea, codice html articolato e lungo che deve essere mantenuto e modificato spesso. L'esempio è stato fatto sui tag semantici, nulla toglie si possa replicare per qualsiasi frammento di codice html, tag, contenitore vario. Non è un mistero per il lettore attento, se un sito web diventa in questo modo un patchwork di "componenti", parti più o meno riutilizzabili una o più volte all'interno di una pagina o di un sito web.

 

Semplificare l'uso di configurazioni

 Negli esercizi più impegnativi pubblicati in queste pagine utilizziamo, per ovvi motivi, il database MySQL. Il codice parziale per collegarsi ad un database da interrogare potrebbe assomigliare al seguente:

$mysql_host = 'localhost';
$mysql_user = 'test';
$mysql_pass = 'test';
$mysql_db = 'test';

/* Connessione e selezione del database */
$connessione = mysqli_connect($mysql_host,$mysql_user,$mysql_pass, $mysql_db);

/** ... query ... */

Questo è un altro esempio lampante di codice ripetuto in modo inutile che può essere semplificato con un include o il suo corrispettivo require  che agisce nel medesimo modo ma più stringente poiché, se per qualche motivo il codice e il suo script non possono essere inclusi o raggiunti, lo script che richiede il caricamento viene arrestato nella sua esecuzione, con ovvi vantaggi sulla sicurezza.

 config.php

$mysql_host = 'localhost';
$mysql_user = 'test';
$mysql_pass = 'test';
$mysql_db = 'test';

e il frammento originale che si trasforma in:

require 'config.php';

/* Connessione e selezione del database */
$connessione = mysqli_connect($mysql_host,$mysql_user,$mysql_pass, $mysql_db);

/** ... query ... */

dove vediamo che le funzione include e require possono essere usate equivalentemente con e senza le parentesi tonde e il parametro del file annesso. In genere web-app complesse possono avere più file di configurazione con svariati nomi più esplicativi come ad esempio config.db.php o utilizzare cartelle e gerarchie su misura inc/config.db.php. 
Suddividendo le variabili della configurazione, metti caso si volesse cambiare database, o credenziali di autenticazione, basterebbe modificare questo file per aggiornare automaticamente tutte le query e similari.

Includere funzioni scritte da noi

Arrivati a questo punto, non è una sorpresa per il lettore che invece di porzioni di codice html o variabili di configurazione, ad essere richiamate in inclusione siano funzioni o frammenti di codice generico php, che magari vogliamo tenere diviso dal normale flusso della pagina e richiamarlo solo al momento di necessità. Facciamo un esempio banale.

<?php

//funzioni aggiuntive
function fuffa(_testo)
{
   echo "Stampo un "._testo;
}

funcition saluta(_saluto)
{
   echo _saluto;
}
 
//codice della pagina
fuffa("ciao");
echo "<br>";
saluta("come stai?");

?>

 In questo frammento c'è la funzione fuffa e saluta che sono poco leggibili e per snellire lo script possiamo procedere a suddividere i codici in due file

funzioni.php

<?php

//funzioni aggiuntive
function fuffa(_testo)
{
   echo "Stampo un "._testo;
}

funcition saluta(_saluto)
{
   echo _saluto;
}
 

?>

e lo script principale che si trasforma e ridimensiona:

<?php

include_once("funzioni.php")
 
//codice della pagina
fuffa("ciao");
echo "<br>";
saluta("come stai?");

?>

qui alla funzione include è stato aggiunto l'operatore _once per indicare che l'inclusione deve essere fatta una sola volta. In questo script non ha molto senso probabilmente, ma in webapp complesse gli script otrebbero includersi e richiamarsi ricorsivamente duplicando magari alcune porzioni di codice. E' buona norma assicurarsi che le include e require siano fatte una sola volta o usare include_once e require_once per debuggare il codice.

Includere librerie esterne

Ultimo ma probabilmente più intuitivo e scontato. Se al nostro codice dobbiamo aggiungere una funzionalità esterna, una libreria di terze parti, sarà possibile usare le nostre funzioni include e require avendo premura di seguire le istruzioni del produttore/fornitore che segnala file e path da includere. Su questo sito trovate ad esempio un post dedicato all'uso della libreria php fpdf che ha uno stralcio di utilizzo come sotto riportato. Le funzionalità e gli oggetti FPDF non sono standard e necessitano dell'include iniziale per poter essere utilizzate all'interno dello script. Ovviamente il lettore noterà che c'è una cartella fpdf che conterrà tutti gli script necessari alla funzionalità per espletare le proprie competenze.

<?php
include ('fpdf/fpdf.php');

// crea PDF

$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial', 'B', 16);
$pdf->Cell(40, 10, 'Report biciclette utente'.$utente);
$pdf->Ln();

Stampa