Obtenir le chemin absolu du script exécuté initialement


247

J'ai cherché haut et bas et j'obtiens beaucoup de différentes solutions et variables contenant des informations pour obtenir le chemin absolu. Mais ils semblent fonctionner dans certaines conditions et pas dans d'autres. Existe-t-il une solution miracle pour obtenir le chemin absolu du script exécuté en PHP? Pour moi, le script s'exécutera à partir de la ligne de commande, mais une solution devrait fonctionner aussi bien si elle est exécutée dans Apache, etc.

Clarification: le script initialement exécuté, pas nécessairement le fichier où la solution est codée.


vrai en effet mathheadinclouds. Je l'ai accepté il y a longtemps quand je n'avais qu'un seul script et cela a fonctionné pour moi. J'ai supprimé la réponse acceptée pour indiquer clairement qu'elle ne résout pas le problème initial. Stocker la constante FILE au début de l'exécution dans un script est une solution, mais loin d'être idéale.
inquam

le script demandé est ce que vous vouliez, le script actuel = avec ce code de solution
Bitterblue

Réponses:


33

La bonne solution consiste à utiliser la get_included_filesfonction:

list($scriptPath) = get_included_files();

Cela vous donnera le chemin absolu du script initial même si:

  • Cette fonction est placée dans un fichier inclus
  • Le répertoire de travail actuel est différent du répertoire du script initial
  • Le script est exécuté avec la CLI, comme chemin relatif

Voici deux scripts de test; le script principal et un fichier inclus:

# C:\Users\Redacted\Desktop\main.php
include __DIR__ . DIRECTORY_SEPARATOR . 'include.php';
echoScriptPath();

# C:\Users\Redacted\Desktop\include.php
function echoScriptPath() {
    list($scriptPath) = get_included_files();
    echo 'The script being executed is ' . $scriptPath;
}

Et le résultat; notez le répertoire courant:

C:\>php C:\Users\Redacted\Desktop\main.php
The script being executed is C:\Users\Redacted\Desktop\main.php

Cette solution fonctionne mais il convient de mentionner qu'à la lecture de la documentation , il n'est pas fait mention que le chemin du script exécuté initialement est le premier élément du tableau renvoyé par get_included_files(). Je suggère de stocker __FILE__dans une constante au début du script destiné à être exécuté initialement.
Paolo

270

__FILE__ constante vous donnera un chemin absolu vers le fichier actuel.

Mise à jour :

La question a été modifiée pour demander comment récupérer le script initialement exécuté au lieu du script en cours d'exécution. La seule (??) manière fiable de le faire est d'utiliser la debug_backtracefonction.

$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];

Si j'utilise un modèle de contrôleur frontal. Serait __FILE__retourner l'emplacement de l'index.php ou l'emplacement du fichier inclus? Comment puis-je obtenir l'emplacement de index.php?
CMCDragonkai

Bien __FILE__indique le chemin du script actuel. Mais je n'ai rien trouvé pour montrer le chemin actuel de index.php.
CMCDragonkai

1
@CMCDragonkai: posez ensuite une question distincte
zerkms

2
ATTENTION: si le script se trouve dans un répertoire virtuel apache2, les informations renvoyées ne fournissent PAS l'emplacement réel du chemin sur le serveur physique. Je le voulais à des fins de débogage, et même les variables $ _SERVER ne le fournissent pas. Par exemple, si index.php existe dans / var / www / vpath1 / html et / var / www / html / et / var / www / vpath2 / html, et que chacun d'eux est virtuellement mappé sur / var / www / html, alors / var / www / html est ce que vous verrez, quel que soit le serveur virtuel utilisé.
Mark Richards

1
@ChristofferBubach vous n'avez même pas besoin de le lancer: un objet d'exception collecte la trace de la pile pendant la construction.
zerkms

262

La réponse a été déplacée ici - https://stackoverflow.com/a/26944636/2377343


1
pour obtenir le dossier actuel du scriptstr_replace( basename(__FILE__) , '',str_replace($_SERVER["DOCUMENT_ROOT"],'',str_replace('\\','/',__FILE__ ) ) ) === /folder1/folder2/
Salem

2
C'est de loin la liste la plus complète d'exemples de moyens d'obtenir une partie ou la totalité du chemin de fichier que j'ai vu sur Internet.
Sean the Bean

241
echo realpath(dirname(__FILE__));

Si vous le placez dans un fichier inclus, il imprime le chemin d'accès à cette inclusion. Pour obtenir le chemin du script parent, remplacez __FILE__par $_SERVER['PHP_SELF']. Mais sachez que PHP_SELF est un risque pour la sécurité!


1
C'était exactement ce que je voulais
enquête

13
à quoi sert realpath ici?
Votre bon sens le

11
@Col. Shrapnel: "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." plus "dirname () fonctionne naïvement sur la chaîne d'entrée et ne connaît pas le système de fichiers réel, ni les composants de chemin tels que '..'.
rik

6
oh, 4.0.2. Le siècle dernier?
Votre bon sens le

2
@rik: aussi, quel problème de sécurité peut causer PHP_SELF??
zerkms

38
__DIR__

Du manuel :

Le répertoire du fichier. S'il est utilisé dans une inclusion, le répertoire du fichier inclus est retourné. C'est équivalent à dirname(__FILE__). Ce nom de répertoire n'a pas de barre oblique de fin sauf s'il s'agit du répertoire racine.
__FILE__ contient toujours un chemin absolu avec des liens symboliques résolus alors que dans les versions plus anciennes (que 4.0.2) il contenait un chemin relatif dans certaines circonstances.

Remarque : a __DIR__été ajouté en PHP 5.3.0.



8
dirname(__FILE__) 

donnera l' itinéraire absolu du fichier courant à partir duquel vous demandez l'itinéraire, l'itinéraire de votre répertoire de serveur.

fichiers d'exemple:

www / http / html / index.php; si vous placez ce code dans votre index.php, il renverra:

<?php echo dirname(__FILE__); // this will return: www/http/html/

www / http / html / class / myclass.php; si vous placez ce code dans votre myclass.php, il renverra:

<?php echo dirname(__FILE__); // this will return: www/http/html/class/


7

Utilisez simplement ci-dessous:

echo __DIR__;

1
Sry, l'idée est d'obtenir le premier script viré ... Pas celui dans lequel vous vous trouvez actuellement. Ainsi, un arbre d'inclusion de a.php->b.php->c.phpdevrait être le chemin d'accès de a.php s'il est coché dans c.php . La seule façon qui semble fiable est d'utiliser la fonction debug_backtrace () .
enquête

5
`realpath(dirname(__FILE__))` 

il vous donne le répertoire du script actuel (le script dans lequel vous avez placé ce code) sans barre oblique de fin. c'est important si vous voulez inclure d'autres fichiers avec le résultat


Oui, mais l'idée est de pouvoir obtenir le chemin absolu vers le "script de tir" A.php même à l'intérieur de B.php si cela est inclus par A.php. Cela PEUT ou bien sûr être fait en stockant le script initial pour un accès ultérieur, mais la question était de savoir s'il était possible de l'obtenir sans le faire.
inquam

4

Si vous recherchez le chemin absolu par rapport à la racine du serveur, j'ai trouvé que cela fonctionne bien:

$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])

Lorsque je vérifiais cette solution sur différents serveurs, cela me donnait toujours un chemin avec les séparateurs dir comme linux quel que soit le système d'exploitation de l'hôte (Windows et Linux). Pour moi, c'est un avantage.
Bronek

3

Voici une fonction PHP utile que j'ai écrite pour cela précisément. Comme la question d'origine le clarifie, elle renvoie le chemin à partir duquel le script initial a été exécuté - pas le fichier dans lequel nous sommes actuellement.

/**
 * Get the file path/dir from which a script/function was initially executed
 * 
 * @param bool $include_filename include/exclude filename in the return string
 * @return string
 */ 
function get_function_origin_path($include_filename = true) {
    $bt = debug_backtrace();
    array_shift($bt);
    if ( array_key_exists(0, $bt) && array_key_exists('file', $bt[0]) ) {
        $file_path = $bt[0]['file'];
        if ( $include_filename === false ) {
            $file_path = str_replace(basename($file_path), '', $file_path);
        }
    } else {
        $file_path = null;
    }
    return $file_path;
}


1
realpath($_SERVER['SCRIPT_FILENAME'])

Pour le script exécuté sous le serveur Web $_SERVER['SCRIPT_FILENAME'], le chemin d'accès complet au script initialement appelé sera contenu, donc probablement votre index.php. realpath()n'est pas requis dans ce cas.

Pour le script exécuté à partir de la console, $_SERVER['SCRIPT_FILENAME']il contiendra un chemin d'accès relatif à votre script initialement appelé à partir de votre répertoire de travail actuel. Donc, à moins que vous n'ayez modifié le répertoire de travail dans votre script, il se résoudra en chemin absolu.


1

C'est ce que j'utilise et cela fonctionne dans les environnements Linux. Je ne pense pas que cela fonctionnerait sur une machine Windows ...

//define canonicalized absolute pathname for the script
if(substr($_SERVER['SCRIPT_NAME'],0,1) == DIRECTORY_SEPARATOR) {
    //does the script name start with the directory separator?
    //if so, the path is defined from root; may have symbolic references so still use realpath()
    $script = realpath($_SERVER['SCRIPT_NAME']);
} else {
    //otherwise prefix script name with the current working directory
    //and use realpath() to resolve symbolic references
    $script = realpath(getcwd() . DIRECTORY_SEPARATOR . $_SERVER['SCRIPT_NAME']);
}

1

Une façon simple d'avoir le chemin absolu du script exécuté d' abord , dans ce script et tout autre script inclus avec include, require, require_onceest à l'aide d' une constante et le stockage il le chemin du script en cours au début du script principal :

define( 'SCRIPT_ROOT', __FILE__ );

La solution ci-dessus convient quand il existe un seul script "principal" qui correspond à includetous les autres scripts nécessaires, comme dans la plupart des applications Web.

Si ce n'est pas le cas et qu'il peut y avoir plusieurs "scripts initiaux", alors pour éviter les redéfinitions et pour avoir le chemin correct stocké dans la constante, chaque script peut commencer par:

if( ! defined( 'SCRIPT_ROOT' ) ) {
    define( 'SCRIPT_ROOT`, __FILE__ );
}

Une note sur la réponse (actuellement) acceptée :

la réponse indique que le chemin du script initialement exécuté est le premier élément du tableau renvoyé par get_included_files().

Il s'agit d'une solution intelligente et simple et -au moment de l'écriture- (nous sommes presque à PHP 7.4.0) cela fonctionne .

Cependant, en regardant la documentation, il n'est pas mentionné que le script initialement exécuté est le premier élément du tableau retourné par get_included_files().

Nous lisons seulement

Le script appelé à l'origine est considéré comme un "fichier inclus", il sera donc répertorié avec les fichiers référencés par include et family.

Au moment de l'écriture, le " script appelé à l'origine " est le premier du tableau mais - techniquement - il n'y a aucune garantie que cela ne changera pas à l'avenir.


Une note sur realpath(), __FILE__et __DIR__:

D' autres ont suggéré dans leurs réponses l'utilisation de __FILE__, __DIR__, dirname(__FILE__), realpath(__DIR__)...

dirname(__FILE__)est égal à __DIR__(introduit en PHP 5.3.0), il suffit donc de l'utiliser __DIR__.

Les deux __FILE__et __DIR__sont toujours des chemins absolus, il realpath()n'est donc pas nécessaire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.