Introduction à l'inclusion des fichiers sous PHP

Il y a 4 moyens de construire l'inclusion des fichiers dans vos scripts PHP. L'objectif étant de créer du code dans un fichier séparé et d'être capable de l'éxecuter. Deux options sont possibles. La fonction include() ou la fonction require().

La construction include()

Cette construction est très utilisé, si le fichier n'existe pas seulement un warning est retourné et le script continu d'être executé.

<?php
include($_SERVER['DOCUMENT_ROOT'].'/myfile.php');
?>

 

Tout le code et les fonctions dans le fichier myfile.php est disponible pour tout le reste du script PHP.

La construction include_once()

Ok, the main difference between the include_once() construct and the include() construct is that if the file has already been included in this code execution, it will not be included again. This is a good method to use and I would recommend it above using the standard include() construct because it can prevent you from redeclaring functions that you may have already included previously. As your code becomes more complex, you may have files included in different files and when calling those files, you may start running into problems.

My recommendation: if you need to include a file using one of the include methods, use include_once() as the preference for construct of choice!

<?php
include_once($_SERVER['DOCUMENT_ROOT'].'/myfile.php');
?>

 

La construction require()

La construction require est la même que include(), à une différence majeur. Si le fichier n'existe pas, ou ne peut pas être inclus, une erreur fatal est géneré et l'execution du script PHP est arreté! Cette construction est importante pour les applications qui requièrent des dépendances depuis d'autres fichiers, qui doivent être fait dans un certain ordre pour que le script fonctionne correctement.

<?php
require($_SERVER['DOCUMENT_ROOT'].'/myfile.php');<br />
?>

 

La construction require_once()

Cette contruction est certainement celle que j'utilise le plus comparé aux 3 autres. Comme include_once(), require_once() détermine si le fichier à déjà été inclus. De plus une erreur fatal est géneré comme avec require() si le fichier ne peut être lu ou inclus.

<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/myfile.php');
?>

 

Fichiers et chemins

Pour comprendre les chemins, il y a plusieurs choses à considérer. Principalement la portabilité! Si vous développez un site sur une machine local et que vous définissez le chemin complet du fichier, vous rencontrerez des problèmes sur le serveur de développement car vos chemins seront différents. La meilleure solution pour résoudre ce problème est d'utiliser la variable superglobal $_SERVER['DOCUMENT_ROOT'] qui est défini par la configuration serveur.

Jeff développe son site sur sa machine local. Il utilise Windows, Apache, MySQL and PHP. Son Document Root est C:\myweb\public_html. Lorsque Jeff inclut un fichier, il utilise un code comme ceci:

<?php
require_once('C:\myweb\public_html\myfile.php');
?>

 

Quand Jeff envoie son fichier sur un serveur Linux, son Document Root devrait être: /home/jeff/public_html et on voit clairement que nous allons avoir un problème! Cependant Jeff devrait utiliser la variable superglobal pour inclure ces fichiers afin que son code soit plus portable et fonctionne aussi also work both on Windows and Linux. Il pourra ainsi envoyer ces fichiers sur n'importe quel serveur aussi longtemps qu'il utilisera le même Document Root.

<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/myfile.php');
?>

 

Utiliser des Shortucts ou Working Directory Paths : si vous êtes familier avec le système de fichier, vous pouvez utiliser ces méthodes. Cependant, il n'est pas recommandé de l'utiliser! Un autre exemple, Jeff sait que le fichier qu'il souhaite inclure est dans le même répertoire. Il peut simplement inclure son fichier :

<?php
require_once('myfile.php');
?>

 

Si Jeff veut retourner au Document Root, il peut simplement

<?php
require_once('./myfile.php');
?>

 

Si Jeff a un fichier dans un répertoire parent :

<?php
require_once('../myfile.php');
?>

 

Si Jeff veut inclure un fichier présent dans un sous répertoire:

<?php
require_once('includes/myfile.php');
?>

 

Les exemples précédent devraient fonctionner, tel que : ./includes/myfile.php, etc. Aussi longtemps que vous savez naviguer dans l'organisation de vos fichiers. Si vous développez un script qui doit être exécuté comme ligne de commande, il est bon de considérer que DOCUMENT_ROOT n'est pas disponible dans la variable $_SERVER. Encore une fois, je crois que pour la portabilité nous sommes sur la bonne voie. Pour inclure des fichiers proprement qui fonctionne en ligne de commande et sur le serveur, utilisons une constante:

<?php
$docroot = dirname(__FILE__).'/';
require_once($docroot.'myfile.php');
?>

 

L'exemple précédent crée un DOCUMENT_ROOT dans $docroot en utilisant la fonction dirname() et la constante __FILE__ . Le résultat sera exactement le même que $_SERVER['DOCUMENT_ROOT']. Encore une fois, si vous gardez tout dans le répertoire de travail et que vous incluez et executez toujours les fichiers dans ce répertoire, vous pouvez passer cette astuces en utilisant des raccourcis. Cependant, Je vous conseil d'utiliser cette méthode pour vous assurer que votre code est portable et fonctionnera en toutes circonstances.

Passons maintenant à la sécurité avec l'inclusion des fichiers. Seul les permissions de lecture sont nécessairesur le serveur. Inclure des fichier NON-PHP, par exemple, un fichier texte, ce fichier sera affiché avec le script PHP. Par exemple, un CSS, ou un fichier de mot de pass, ou tout autre fichier que l'on peut afficher et accessible depuis le web peut créer un risque de sécurité. Ne jamais inclure, lire, exécuter, supprimer un fichier basé sur une entré utilisateur, à travers les méthodes $_POST, $_REQUEST ou $_GET, etc. MAUVAIS EXEMPLE !!



<?php
// My UNcool CSS include script.
echo '<html>';
echo '<head>';
echo '<title>;My Bad CSS Example</title>';
// Create a security hole!
include($_GET['css_file']);
// End security hole!
echo '</head>';
// the rest.......
?>

Un utilisateur malicieux peut utiliser cette URL http://yourdomain.com?css_file=/etc/shadow. Ainsi, il aurait accès au fichier /etc/shadow. Les fonctions que vous devez protéger des interventions utilisateurs sont show_source(), higlight_file(), file_get_contents(), readfile(), fopen(), fpassthru(), exec(), shell_exec(), et toutes les autres fonctions qui peuvent exécuter, lire, afficher, copier et supprimer des fichiers!

Notes : Open Base Directory (open_basedir) et Safe Mode permettent d'améliorer la sécurité en empêchant l'accès aux fichiers dans certaine partie du système de fichier.

Résumé :

L'utilisation des chemins absolus est fortement conseillés dans les applications qui manipulent des fichiers.


Cependant il n'est pas toujours facile de connaître l'arborescence du serveur qui héberge votre application et de plus celle-ci est ammennée à changer. De plus, si le chemin a transité par l'utilisateur, qu'il soit donné ou transmis, il est important de le valider pour qu'il ne se dédouble pas.


Une solution simple et rapide à mettre en place est l'utilisation de la fonction realpath() pour nettoyer le chemin absolu d'un fichier. De plus la fonction realpath() permet de résoudre les liens sympboliques.



<?php
    require_once realpath('../../config/application.conf.php');
?>




La fonction realpath() peut être couplé avec les fonctions dirname() (renvoi le nom du dossier d'un fichier) et basename() (renvoi le nom du fichier d'un chemin).


Mon fichier index.php doit inclure un fichier init.inc.php situé dans un dosser includes, lui même situé dans le même dossier que le fichier index.php.


L'arborescence est la suivante :

application/

includes/

init.inc.php

index.php



La première idée serait d'utiliser la manière suivante









<?php
    require_once realpath('./includes/init.inc.php');
?>


Le problème de cette solution est que si l'inclusion est précédée d'un changement de dossier via la fonction chdir() par exemple, votre inclusion échouera.


Une solution pour résoudre ce problème est d'utiliser la variable __FILE__ qui retourne le nom du fichier dans lequel elle est appellée et la fonction dirname() qui va nous retourner le nom du dossier de ce fichier.

<?php
//Changer le r&eacute;pertoire courant
chdir('../../'); 
//Le <a href="http://www.php.net/chdir">chdir()</a> au dessus n'aura pas de cons&eacute;quence sur le chemin d'inclusion du fichier
require_once realpath(dirname(__FILE__) . './includes/init.inc.php');
?>



Enfin la fonction pathinfo() permet d'obtenir le chemin du fichier, le nom du fichier, ainsi que son extension.

<?php
    print_r(__FILE__);
    /**
     * Array
     * (
     *     [dirname] => /home/mon_compte/public_html
     *     [basename] => index.php
     *     [extension] => php
     *     [filename] => index
     */
?>

N'utilisez pas la fonction pathinfo() pour déterminer le type du fichier. Utilisez plutôt l'extension Fileinfo.
Avec tous ces explications, je pense qu'il ne devrait plus y avoir de problème.

Ce tutoriel couvre les aspects basiques de l'inclusion des fichiers mais n'est certainement pas une référence en soit. Bon developpement!