dirname(__FILE__), où comment éviter d'utiliser define('ROOT',...);
Comment récupérer le répertoire courant du fichier dans lequel on se trouve ...
La technique du dirname(FILE)
/** * Exemples: * * /home/moi-meme/public_html/index.php => /home/moi-meme/public_html * c:\public_html\index.php => c:\public_html */ $cwd = dirname(__FILE__);
Si vous voulez le chemin réel sur la machine (enlever les lien symboliques et les ../), vous pouvez aussi faire :
/** * Exemples: * * /home/moi-meme/public_html/index.php => /var/users/moi-meme/public_html (avec lien symbolique de /home vers /var/users) * c:\public_html\index.php => c:/public_html */ $cwd = realpath(dirname(__FILE__));
Pour obtenir un chemin normalisé avec des / au lieu de \ sur windows (utile pour le cross plateforme windows/linux ou pour la comparaison de sous-chaîne sans se soucier de la plateforme) :
/** * Exemples: * * /home/moi-meme/public_html/index.php => /home/moi-meme/public_html * c:\public_html\index.php => c:/public_html */ $cwd = str_replace(DIRECTORY_SEPARATOR,'/',realpath(dirname(__FILE__)));
La technique du dirname(FILE).'/../'
Comme lorsque vous êtes dans un fichier vous savez où il se trouve relativement par rapport aux autres (par exemple mon fichier ./includes/functions.php, je sais qu'il est dans le sous-répertoire includes à partir de la racine de mon application), vous pouvez ensuite vous servir de se "positionnement" relatif pour include des fichiers :
Dans le fichier ./includes/all.php
require_once dirname(__FILE__).'/functions/database.php'; ...
Imaginez que vous ayiez un répertoire ./html/ qui contient index.php et un répertoire ./includes/ qui contient le fichier functions.php (de sorte que le fichier functions.php ne soit pas directement accessible dans l'arborescence du serveur web qui pointe sur ./html) .
Vous pouvez donc include le fichier functions.php de la manière suivante dans le fichier index.php :
require_once dirname(__FILE__).'/../includes/functions.php'; ...
même si vous déplacez votre application dans un autre répertoire du système ou sur un autre serveur, tant que l'arborescence des fichiers de votre application ne change pas, il n'y a aucun impact sur votre code source !
Plus besoin de tenir (pour ceux qui n'utilisaient pas déjà cette technique) un fichier de configuration avec des define qui est a modifié à chaque installation.
Et vous comment gérez vous les chemins absolus (inclusions de fichiers ou lecture de fichier sur le disque) dans vos applications ?
Commentaires
Je ne pense pas que dirname( __FILE__ ) remplace le define( 'ROOT' , <dir> ).
L'un n'a rien avoir avec l'autre.
L'utilisation d'une constante qui pointe sur la racine est très utile : pour former un path sans avoir de ROOT, on doit jongler avec les '/..' etc.
L'inclusion dans les autoloader de class (spl_autoload_register), de déplacement au sein du filesystem du code, etc., sont entièrement facilités par une constante "ROOT". Les chemins relatifs portent trop souvent à confusion.
De plus, le fait de définir le ROOT à partir de dirname( __FILE__ ) fait qu'il est absurde de dire une bêtise comme :
"Plus besoin de tenir un fichier de configuration avec des define qui est a modifié à chaque installation."
Encore une fois, l'un et l'autre sont deux choses différentes.
De plus, il aurait été intéressant de préciser qu'à partir de la version 5.3, la constante __DIR__ offre l'équivalent d'un dirname( __FILE__ );
@avetis.kazarian: tout est histoire de pratique, il n'y pas de bonnes et mauvaises pratiques universelles, cependant certaines pratiques sont plus adaptées que d'autres dans certaines situations.
Un fichier qui utilise le principe de dirname(__FILE__) pour inclure ses dépendances, est potentiellement utilisable directement par une autre application ou script, si il nécessite la présence de constantes (ex: ROOT) alors il faudra au préalable définir ces constantes avant d'utiliser ce fichier dans une autre application.
Effectivement, cela n'a pas de réelle importance lorsque l'on développe une application autonome, mais en prend lorsque l'on décide de rendre potentiellement mutualisable à toutes nos applications/scripts tous les développements que nous réalisons.
Attention aux "dépendances" implicites de notre code à des éléments extérieurs (define, variable globales, fichiers de configuration...) ils rendent difficilement testable ou utilisable dans un autre contexte notre code.
Merci pour la précision sur la constante __DIR__ en PHP 5.3, pour toutes les applications legacy des S.I français (et autres !) qui ne pourront pas bénéficier de la 5.3 avant quelques mois voir années, dirname(__FILE__) reste utilisable en attendant...