Comment inclure des fichiers PHP qui nécessitent un chemin absolu?

95

J'ai une structure de répertoires comme celle-ci;

script.php

inc / include1.php
inc / include2.php

objets / object1.php
objets / object2.php

savon / savon.php

Maintenant, j'utilise ces objets dans les deux script.phpet /soap/soap.php, je pourrais les déplacer, mais je veux la structure de répertoire comme ça pour une raison spécifique. Lors de l' exécution script.phpdu include_path est inc/include.phpet lors de l' exécution , /soap/soap.phpil est ../inc, le travail de chemins absolu, /mnt/webdev/[project name]/inc/include1.php...mais il est une solution laide si je veux jamais déplacer le répertoire vers un autre emplacement.

Existe-t-il donc un moyen d'utiliser des chemins relatifs, ou un moyen de générer par programme le "/mnt/webdev/[project name]/"?

Xenph Yan
la source

Réponses:

149

Cela devrait fonctionner

$root = realpath($_SERVER["DOCUMENT_ROOT"]);

include "$root/inc/include1.php";

Edit: ajout de l'importance par Aussieviking

Peter Coulton
la source
2
Attention, cela ne fonctionnera que si vous exécutez le script via un serveur Web qui se remplitDOCUMENT_ROOT
Phil
juste une question, pourquoi realpath () pour $ _SERVER ["DOCUMENT_ROOT"]? Cela ne doit pas toujours afficher le chemin canonique?
João Pimentel Ferreira
44

Vous pouvez utiliser des chemins relatifs. Essayez __FILE__. C'est une constante PHP qui retourne toujours le chemin / nom de fichier du script dans lequel il se trouve. Donc, dans soap.php, vous pouvez faire:

include dirname(__FILE__).'/../inc/include.php';

Le chemin complet et le nom de fichier du fichier. S'il est utilisé dans un include, le nom du fichier inclus est renvoyé. Depuis PHP 4.0.2, __FILE__contient toujours un chemin absolu avec des liens symboliques résolus alors que dans les anciennes versions, il contenait un chemin relatif dans certaines circonstances. (la source)

Une autre solution serait de définir un chemin d'inclusion dans votre httpd.conf ou dans un fichier .htaccess.

Kevin
la source
8
Je pense que vous devriez ajouter un /au début de l'expression citée, pour séparer le ..du nom FILE .
Dunaril
9
Notez que depuis PHP 5.3.0, vous pouvez utiliser la constante magique __DIR__plutôt que d'avoir à utiliser dirname(__FILE__). (Documentation PHP)
Erwin Wessels
3
include dirname(__FILE__).'/../inc/include.php';N'oubliez pas le "/" avant le chemin relatif.
Steven Leimberg le
6

Une autre façon de gérer cela qui supprime tout besoin d'inclusion est d'utiliser la fonction de chargement automatique. Inclure tout ce dont votre script a besoin "Just in Case" peut nuire aux performances. Si vos inclusions sont toutes des définitions de classe ou d'interface et que vous souhaitez les charger uniquement lorsque cela est nécessaire, vous pouvez surcharger la __autoload()fonction avec votre propre code pour trouver le fichier de classe approprié et le charger uniquement lorsqu'il est appelé. Voici l'exemple du manuel:

function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

Tant que vous définissez vos variables include_path en conséquence, vous n'aurez plus jamais besoin d'inclure à nouveau un fichier de classe.

Sam McAfee
la source
5

Vous pouvez définir une constante avec le chemin d'accès au répertoire racine de votre projet, puis la placer au début du chemin.

Ryan Fox
la source
2

Une autre option, liée à celle de Kevin, est d'utiliser __FILE__, mais à la place de remplacer le nom du fichier php à l'intérieur:

<?php

$docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__);
require_once($docRoot . '/lib/include.php');

?>

J'utilise ça depuis un moment. Le seul problème est que parfois vous n'en avez pas $_SERVER['SCRIPT_NAME'], mais parfois il y a une autre variable similaire.

Darryl Hein
la source
2

J'ai trouvé que cela fonctionnait très bien!

function findRoot() { 
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

Utilisation:

<?php

function findRoot() {
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

include(findRoot() . 'Post.php');
$posts = getPosts(findRoot() . 'posts_content');

include(findRoot() . 'includes/head.php');

for ($i=(sizeof($posts)-1); 0 <= $i; $i--) {
    $posts[$i]->displayArticle();
}

include(findRoot() . 'includes/footer.php');

?>
Thane Gill
la source
1

Je pense que le meilleur moyen est de mettre vos includes dans votre chemin d'inclusion PHP. Il existe différentes façons de procéder en fonction de votre configuration.

Ensuite, vous pouvez simplement vous référer à

require_once 'inc1.php';

de l'intérieur de n'importe quel fichier, peu importe où il se trouve, que ce soit dans vos fichiers inclus ou accessibles sur le Web, ou à tout niveau de sous-répertoires imbriqués.

Cela vous permet d'avoir vos fichiers d'inclusion en dehors de la racine du serveur Web, ce qui est une bonne pratique.

par exemple

site directory
    html (web root)
        your web-accessible files
    includes
        your include files

Consultez également __autoload pour le chargement paresseux des fichiers de classe

http://www.google.com/search?q=setting+php+include+path

http://www.google.com/search?q=__autoload

Polsonby
la source
1
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php");

J'utilise cette ligne de code. Il remonte en "haut" de l'arborescence du site, puis va au fichier souhaité.

Par exemple, disons que j'ai cette arborescence de fichiers:

domain.com/aaa/index.php
domain.com/bbb/ccc/ddd/index.php
domain.com/_resources/functions.php

Je peux inclure le fichier functions.php où que je sois, simplement en copiant-collant

require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/_resources/functions.php");

Si vous devez utiliser ce code plusieurs fois, vous pouvez créer une fonction qui renvoie la str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))pièce. Ensuite, insérez simplement cette fonction dans le premier fichier que vous incluez. J'ai un fichier "initialize.php" que j'inclus tout en haut de chaque page php et qui contient cette fonction. La prochaine fois que je dois inclure des fichiers, j'utilise en fait simplement la fonction (nommée path_back):

require(path_back()."/_resources/another_php_file.php");
Machavity
la source
0

@Flubba, est-ce que cela me permet d'avoir des dossiers dans mon répertoire d'inclusion? plat inclure les répertoires me donnent des cauchemars. car tout le répertoire des objets doit se trouver dans le répertoire inc.

Oh oui, absolument. Ainsi, par exemple, nous utilisons une seule couche de sous-dossiers, généralement:

require_once('library/string.class.php')

Vous devez faire attention à ne pas trop vous fier au chemin d'inclusion dans les sites à très fort trafic, car php doit parcourir le répertoire actuel, puis tous les répertoires sur le chemin d'inclusion afin de voir si votre fichier est là et cela peut ralentir les choses se passent si vous êtes martelé.

Donc, par exemple, si vous faites MVC, vous mettez le chemin de votre application directoy dans le chemin d'inclusion, puis spécifiez faire référence aux choses dans le formulaire

'model/user.class'
'controllers/front.php'

ou peu importe.

Mais d'une manière générale, cela vous permet simplement de travailler avec des chemins vraiment courts dans votre PHP qui fonctionneront de n'importe où et c'est beaucoup plus facile à lire que tout ce malarkey de racine de document realpath.

L'avantage de ces alternatives basées sur des scripts que d'autres ont suggérées est qu'elles fonctionnent n'importe où, même sur des boîtes partagées; définir le chemin d'inclusion nécessite un peu plus de réflexion et d'efforts, mais comme je l'ai mentionné, vous permet de commencer à utiliser __autoload, ce qui est juste le plus cool.

Polsonby
la source
0

Si vous prévoyez d'inclure un chemin d'accès spécifique dans la plupart des fichiers de votre application, créez une variable globale dans votre dossier racine.

define("APPLICATION_PATH", realpath(dirname(__FILE__) . '/../app'));
or 
define("APPLICATION_PATH", realpath(DIR(__FILE__) . '/../app'));

Maintenant, cette variable globale " APPLICATION_PATH " peut être utilisée pour inclure tous les fichiers au lieu d'appeler realpath () chaque fois que vous incluez un nouveau fichier.

EX:

include(APPLICATION_PATH ."/config/config.ini";

J'espère que ça aide ;-)

yuvraj
la source