Développement

Include et require en PHP

Article par (Intégrateur du Dimanche, Strasbourg)
Créé le , mis à jour le (299008 lectures)
Tags : include, inclure, php, inclusion, fichier, require

Il existe 4 structures de langage en PHP qui sont rudement pratiques pour le développement web, que ce soit pour démarrer un site simple ou faire tourner une application web plus complexe avec un CMS et/ou une base de données :

  • require : inclut le contenu d'un autre fichier appelé, et provoque une erreur bloquante s'il est indisponible
  • require_once : même chose que require, mais ne le fait qu'une seule fois en tout et pour tout dans le même document, si require a déjà été appelé auparavant avec le même nom de fichier
  • include : inclut le contenu d'un autre fichier appelé, mais ne provoque pas d'erreur bloquante s'il est indisponible
  • include_once : même chose que include, mais ne le fait qu'une seule fois en tout et pour tout dans le même documentsi require a déjà été appelé auparavant avec le même nom de fichier

L'intérêt est de pouvoir "inclure" automatiquement des fichiers communs à l'ensemble - ou à une partie spécifique - du site. Il s'agit souvent de code HTML mais cela fonctionne avec tout ce qui est texte (CSS, JavaScript, etc). Note : ces structures ne sont pas des fonctions à proprement parler, même si l'on peut s'en servir ainsi par permissivité du langage PHP.

Bien souvent on s'arrête à include, mais sa variante include_once est bien pratique pour ne pas répéter une inclusion plusieurs fois par inadvertance (par exemple avec du code PHP plus complexe). De même, require est très intéressant pour "protéger" le fonctionnement d'une page ou application web : si le fichier nécessaire n'est pas accessible alors une erreur sera déclenchée et PHP arrêtera la production du document plutôt que de servir un code HTML incomplet et incohérent.

Usage

Pour inclure un fichier dans un autre à l'aide de PHP, on place l'instruction require (ou include) suivie d'un espace puis du nom du fichier appelé, entre guillemets simples ' ou doubles ".

Code source de fichier1.php

<?php require "fichier2.html"; ?>

Dans quel cas de figure peut-on avoir besoin de mutualiser le code entre différents fichiers ? Pour toutes les parties qui se répètent sur un site !

  • En-tête de page
  • Pied de page
  • Menu de navigation
  • Barre contextuelle
  • Paramètres communs PHP (par exemple connexion à MySQL, variables de configuration, chaînes de texte...)

De façon schématique, voici comment la page principale index.php pourrait faire appel à header.html et footer.html :

Ceci présente nettement plus d'intérêt quand plusieurs fichiers (ici index.php, produits.php et contact.php) vont faire appel aux mêmes sources (header.html et footer.html)

L’utilisation d’un include ou d'un require revient à faire un simple copié-collé : le code du fichier appelé est inséré à l’intérieur de la page appelante, à l’endroit exact où se trouve la fonction. Elle peut être placée n’importe où, à l’intérieur du code source HTML : entre les balises <head> et </head> ou <body> et </body>, par exemple.

Types et extensions de fichiers

Le navigateur ne visualisera qu’un seul et même document avec, en lieu et place de votre include/require le contenu du fichier inclus. Ce dernier peut être de n’importe quel type (HTML, JavaScript, PHP, texte…) et avoir n’importe quelle extension (.htm, .php, .tpl, .kiwi, …) : seul le contenu du fichier importe réellement. Il n’est pas à considérer comme une page à part entière : il n’a pas pour vocation d’être visualisé seul. L’utilisation d’une extension spécifique significative (comme par exemple .inc.php) permet d’avoir une meilleure visibilité et d’éviter ainsi quelques erreurs. Par ailleurs pour éviter toute faille de sécurité, si le fichier inclus comporte lui aussi d'autres instructions de code PHP, il est préférable d'utiliser une extension .php afin que le code soit automatiquement interprété et sa source non visualisable dans le navigateur. Toute autre extension permettrait à quiconque d’avoir accès au contenu du fichier, ce qui pourrait se révéler problématique s’il contenait des données confidentielles, comme par exemple des informations de connexion à une base de données MySQL.

N'oubliez pas qu'il s'agit de structures PHP : il est impératif que l’extension de votre page appelante - dans laquelle figure include ou require - soit de type PHP (avec extension .php) pour que le serveur (s'il est équipé de ce langage, ce qui est le cas de la grande majorité d'entre eux) la traite en tant que telle.

À propos des liens

Afin d’éviter toute erreur, il est préférable d’utiliser des adresses (URLs) absolues, avec le chemin complet par rapport à la racine du site (débutant par un slash initial /). Si le fichier inclus comporte des liens, ceux-ci pointeront toujours relativement à l’adresse de la page appelante. Par conséquent, il suffit qu’un même fichier soit inclus dans des pages de niveaux différents (ex : /fruits/ et /fruits/pommes/ ) pour que les adresses relatives deviennent erronées. Par exemple, pour atteindre un fichier situé dans le dossier fruits/ sur le serveur web, nous préférerons l’écriture absolue <a href="/fruits/kiwi.php">page des kiwis</a> à l’écriture relative <a href="fruits/kiwi.php">page des kiwis</a>. Le / précédant l’url indique au navigateur de prendre pour point de départ la racine du site.

Pour plus d'indications concernant l'écriture des liens (URL) consultez Quelle est la différence entre chemins relatifs et absolus.

Exemple d’utilisation

Nous allons inclure les fichiers header.php et footer.php à l’intérieur de la page index.php. Ci-dessous, le contenu des trois fichiers :

header.php

<!doctupe html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Alsacréations vous conseille de manger des kiwis</title>
<link rel="stylesheet" href="styles.css">
</head>

<header>
  <h1>Titre commun à tout le site</h1>
  <nav>
    <ul>
      <li><a href="index.php">Accueil</a></li>
      <li><a href="contact.php">Contact</a></li>
    </ul>
  </nav>
</header>

footer.php

<footer>
  <p>Mangez des kiwis, ça vous réussit !<br>
  Mais rassurez-vous, une pomme, ça va aussi !</p>
</footer>
</body>
</html>

Notez que le choix d'utiliser des balises <header> et <footer> n'a rien à voir avec le nom des fichiers ou le fonctionnement d'include/require, il s'agit juste d'une heureuse (et logique) coïncidence.

index.php

<?php require 'header.php'; ?>

<p>Bienvenue sur la page d'accueil !</p>

<?php require 'footer.php'; ?>

contact.php

<?php require 'header.php'; ?>

<p>Ceci est le formulaire de contact</p>
<form>
 ...
</form>

<?php require 'footer.php'; ?>

Pour ces deux pages, index.php et contact.php, il sera désormais inutile de répéter le même code pour l'en-tête et le pied de page : celui-ci sera inséré en lieu et place des appels à require ; et ceci pourra être reproduit sur une infinité de pages.

Erreurs courantes

L’erreur la plus classique est l’amalgame qui est fait entre l’utilisation de frames ou d’iframes et d’include. Là où les frames et autres iframes simulent l’insertion d’une page à l’intérieur d’une autre grâce au navigateur, la fonction include() injecte réellement la totalité du fichier, du côté du serveur web.

La deuxième erreur consiste souvent à inclure deux fois le code HTML d'en-tête à partir de fichiers complets (contenant le doctype, les balises <head>, <body>, etc). La page est totalement incohérente et n’a aucune chance d’être interprétée correctement par les navigateurs : il faut absolument que le code source produit au final (vérifiez avec l'affichage du code source par le navigateur) soit propre et non redondant. Si votre fichier d'en-tête contient déjà <!doctype html> et <head>, il ne faut pas les répéter dans les autres fichiers.

Commentaires

pickupjojo a dit le

Merci pour ces petits précisisons, malgré que personnellement j'en connaissais déjà une bonne partie. :-)

shadow84 a dit le

Salut Raphaël!

Un petit mot pour te feliciter pour ton superbe site qui est pour moi une reference sans conteste dans le monde du Webdesign avec CSS! Le top!
Des que mon site sera pret, je ne manquerai pas de te faire un renvoi sur ton site. Avant tout cela, je souhaiterai ton avis et ton conseil sur 2 articles qui figurent sur ton site; voila les references:
css.alsacreations.com/Tut...

css.alsacreations.com/Tut...

Je ne sais pas bien quelle solution choisir. J'ai bien compris les avantages et les incovenients de chaque technique mais le choix reste confus ... Pour ma part, j'ai l'impression que pour un site aboutit en production, la solution de faire une page d'index avec un switch php semble excellente, tandis que pour un site en cours de dev l'include php au debut ou aux endroits propices du site semble convenir ou tout du moins dans un 1er temps. En bref, la solution du switch semble presenter le site dans sa forme la plus rationalisée ...
Qu'en penses tu ? Merci d'avance pour tes lumieres sur la question!

Raphael a dit le

@shadow84 > ben euh j'en pense surtout que ton commentaire n'a pas grand chose à voir avec ce billet de blog :-/
A la rigueur, c'est le genre de questions à poser sur le forum par exemple, tu y trouveras plein de gens compétents et disponibles ;)

solo a dit le

Ma foi, un bon résumé avec un point de vue se plaçant de l'autre coté du traitement serveur :)

Merkel a dit le

Enfin, une petite précision sur les includes. C'est juste dommage que Solo continue à de parler de pseudo-frames. Vous savez pour la plupart à quel point j'ai horreur de ce pseudo terme sortit de nul part et souvent risque de confusion chez les novices... Je parle par expérience, c'est arrivé à de nombreuses reprises que ce terme à suscité des confusions tant au niveau du novice que chez la personne essayant de donner un coup de main.

Merkel a dit le

Arf...pardonnez-moi mes quelques fautes dans mon message précédent. Je suis un peu fatigué ce soir. Dur journée. :p

clb56 a dit le

à raphael

Tout d'abord bonjour :-)

Je continue à penser que les choses ne sont pas encore assez clairement dites y compris dans ta mise au point.

Il faut à mon sens + insister sur les 2 types d'inclusion en jeu :

Par <iframe> ou <object data="page.html"> une page est incluse dans une autre page et ce dans la fenêtre du navigateur.

Par la fonction include du texte brut est inclut dans la source du document html. le fichier mis en <?php include ?> n'a aucune vocation à être ouvert par le navigateur, ce n'est pas une page, ce n'est pas un document html.

Il n'y a pas à enlever les balises <html> etc ... Car la question de leur présence ne se pose même pas puisqu'il ne s'agit en rien d'une page web.

Une difficulté importante du coup se présente car comment faire comprendre que l'on peut inclure fichier_à_inclure.html (ou fichier_à_inclure.php) mais que fichier_à_inclure.html n'est pas une page alors que très précisemment c'en est une, la preuve c'est que si l'on clique dessus c'est bien le logiciel navigateur qui va l'ouvrir.

Comment quelqu'un de peu informer peut-il s'y retrouver dans un tel contexte ?

Je crois vraiment que pour éclaircir les choses le premier point serait d'en rester à des extensions plus significatives des fichiers comme fichier_à_inclure.txt ou .inc (que personnellement je privilégie)

++

solo a dit le

@Merkel,

je suis plus ou moins d'accord avec le fait que le terme est inadapté. Pk pas complètement? Car il faut bien donner un nom au processus et que de manière empirique on en est arrivé à ce terme. Evidemment, tu fais bien de recadrer les novices que tu aides comme la plupart des personnes un peu plus expérimenté par le biais des forums d'entraides.

Pk pas complètement également? car pseudo veut bien dire ce que ça veut dire: ce n'est pas une frame, ni une iframe ^^

Le terme tente de décrire un découpage logique de la page html. Un peu confus donc j'avoue :)

ça ne tiens qu'à nous de populariser un terme plus adapté. Qu'en est-il du coté des anglophones?

Raphael a dit le

@Solo : "ça ne tiens qu'à nous de populariser un terme plus adapté."

> Media-box (dans leur tuto que je n'arrive plus à retrouver) parle de "fichiers réutilisables en PHP"

Bruno a dit le

Bonjour à tous,

>la meilleure des solutions serait d'en rester
>à des extensions plus significatives des
>fichiers comme fichier_à_inclure.txt ou
>fichier_à_inclure.inc. On évite ainsi les
>incompréhensions.

Je déconsille vivement cette méthode, à moins de vraiment savoir ce que l'on fait, je m'explique :
Un serveur configuré normalement n'exécutera pas le code d'un fichier .txt ou .inc si ce fichier est appelé seul, hors de son contexte d'inclusion. La conséquence est que si quelqu'un tombe sur l'url de ce fichier le serveur lui renverra le code source du script en mode texte.

Un exemple facheux : créer un fichier connect.inc contenant ses paramètres de connexion à une base de données (on doit pouvoir trouver de nombreux exemples réels).

Mais si on y tient vraiment, on peut toujours mettre tous ses fichiers inclus dans un répertoire protégé par un .htaccess (deny from all) ou alors adopter la méthode phpmyadmin : fichier.inc.php.
Autre possibilité : configurer son serveur pour qu'il exécute les .inc comme du php, mais il faut avoir la main pour ça.

--
Bruno

Merkel a dit le

"Car il faut bien donner un nom au processus"

Pourquoi vouloir trouver un autre nom que Include ? Pourquoi faut-il absolument trouver un nom original ? Même si on dit pseudo-frames, même si pseudo = faux, on relie quand même ce processus aux frames. Cela n'a rien à voir avec les frames, ni de près, ni de loin, mais ca tu le sais déjà évidemment. Seulement, les novices qui sont déjà très attachés aux frames ont encore plus de mal à se les sortir de la tête. Je déplore l'utilisation du terme pseudo-frames. C'est trop une source de confusion. Je préfère parler d'Include simplement. Pour le reste, le tutorial ou le dialogue suffira à informer le novice comment faire. Le nom du processus n'informe en rien la personne, cela ne fait qu'accentuer sa confusion.

Nyro Xeo a dit le

Je me suis souvent confronté à ce problème (en tant qu'aidant); un débutant qui incluait une page complète dans une autre page complète, il en résultait justement une page avec plusieurs <html>, <body> et autre...

J'ai alors fait un schéma pour mieux "expliquer" le concept qui est de réellement _inclure_ la page dans une autre page. Après quelques remasterisations graphiques (:P) de la part de dib258, voici le schéma : nyro.xeo.online.fr/SdZ/fi...

shadow84 a dit le

Bonsoir à tous,


@Raphaël> Certes, je n'aurais peut etre pas du tourner mon commentaire de la sorte... D'autant plus que c'etait pas tout à fait inline avec la majeure partie de l'article
1)Pseudo-frames ?
2)Attention aux doublons HTML
Ceci dit l'article finissait par:
3)Suivez le bon chemin
Je voulais juste evoquer l'autre possibilité qui se trouve sur ton site... Peut etre plus simple à comprendre pour des débutants mais bien moins rationnalisée et aboutie que le switch... Anyway ca a fait couler de l'encre!
Excuse ma maladresse, c'est la 1ere fois que j'interviens! Y a un début à tout!


@Solo> tres bon aussi ton article


Pour ma part, je trouve la citation reprise par Raphael appropriée : fichiers réutilisables en PHP"
On peut aussi parler d'inclusion de morceau de code au sein d'une page.

A+

jb_gfx a dit le

Et que pensez vous des pseudo includes avec la fonction require()?

C'est pas pour troller mais juste pour dire que je suis à 200% avec Merkel, un include est un include et une frame est une frame point. Sinon on a qu'a appeller le PHP du pseudo HTML tant qu'on y est, puiqu'il permet lui aussi de générer des documents HTML... non mais ça ne viendrait à l'idée de personne de faire ça.

clb56 a dit le

@shadow84> "On peut aussi parler d'inclusion de morceau de code au sein d'une page."

C'est précisemment avec ce genre de terminologie que l'on peut entretenir la confusion.

C'est quoi une page ?
Pour tout un chacun c'est aussi bien la page web telle qu'elle apparait dans la fenêtre du navigateur.

Pourquoi ne pas utiliser l'expression plus strictement technique de code source du document.

Encore une fois même dans le cas de ceux qui veulent mettre les choses au point celà manque de clarté.

martin© a dit le

Je suis d'accord avec le billet, mais je suis surpris qu'il ne parle pas de la fonction readfile() pour l'inclusion de portion d'html pur.

Donc je précise (c'est d'ailleurs signalé dans le billet ) que la fonction include() "inclut et exécute le fichier spécifié en argument". Le point important, c'est que le fichier est executé.
Pour juste inclure du contenu n'ayant pas à être interprété par php, readfile() est plus adapté et économique.
Je précise de plus que le fichier peut trés bien ne pas comporter d'extension (pour include et readfile), dans tous les cas (n'importe quelle extension, ou pas d'extension) include est parsé, et readfile pas.

Raphael a dit le

@martin© > En fait, l'idée de faire un point sur la fonction include() est due au fait que c'est la fonction la plus utilisée pour ce genre de cas (quasiment tout le temps).
Il me semblait donc important de mieux la cerner pour éviter des malentendus.

Personnellement, adepte (comme tout le monde) de include(), je ne connaissais même pas readfile().
Je vais me renseigner sur celle-ci, merci :)

jcm a dit le

Bonjour,

Mon utilisation de "include" :

- dans le cas d'un script qui sera commun à plusieurs pages, par exemple un script formatant uns date en français : il est appelé sur chaque page pour laquelle il sera nécessaire.

- dans le cas d'un script complexe et long, "include" permet de le scinder en différents modules ce qui est simplement une facilité afin de ne pas avoir, dans son éditeur, une très longue page illisible.

Je nomme toujours un include avec une extension "php" par sécurité : une maniaquerie qui évite de stocker des paramètres de connexion à une base de données dans un "inc" auquel tout le monde pourrait accéder.

Je stocke toujours ces "include" dans un répertoire dédié, tout comme les "js" ou "css" : un peu d'ordre ne nuit pas !

Pour moi un "include" est donc un fragment de code php, contenu dans un fichier exécutable pour quelque question de commodité et qui n'a rien de commun avec une "frame" : "frame" signifie "cadre", "monture" (verres), "encadrement", "charpente", "carcasse"...

Que ceux pour lesquels il y aurait encore une confusion pensent à ceci : un "include" n'est qu'une annexe à un script tandis qu'une "frame" est un élément de la structure, généralement graphique, d'une page.

bastien a dit le

include('essai/config.inc.php')
cela marche trés bien mais :
include('../essai/config.inc.php')
pourquoi cela ne fct pas
include ne va pas chercher des fichiers à la source ou en arrière dans l'arborescence de mon site Merci

mike72 a dit le

Salut a tous

Pour ma part j'essaye d'utiliser la fonction include, j'ai recopié le code donné en exemple sur le site, mais chez moi ca ne marche pas. Que se passe t'il ? Je doit présenter mon site le 20 juin a mon directeur
de stage. J'ai besoin d'aide ... Merci tout le monde

Raphael a dit le

@mike72 > heureusement, il y'a un forum fait pour ça sur Alsa :)

gimli a dit le

Personnellement, je comprends pourquoi certaines personnes parlent de pseudo frame. J'ia changé récemment tout monde site, en enlevant les frames, et en mettant à la place des includes (avec une structure en "table", décidemment, j'ai toujours 10 ans de retard... faudrait passer aux DIV)... Mais bon, bien sûr, c'est un include, ce sont deux choses differentes !
Mais sinon ,c'est un très bon tuto ! même si je connaissais déjà.

asene a dit le

Une autre fonction d'include très utile dans certains cas (mais presque jamais utilisée) consiste à l'insérer directement dans les CSS.
Par exemple :

body {
background-color: <? include("coulbody.txt"); ?>;
}

... où la valeur, dans cet exemple, est récupérée dans un fichier texte qui peut être directement écrit en PHP par la fonction fwrite.