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.

inquam
la source
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
Salman A
la source
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'];
zerkms
la source
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

T.Todua
la source
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é!

rik
la source
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.

Gottlieb Notschnabel
la source
21

Si vous souhaitez obtenir le répertoire de travail actuel, utilisezgetcwd()

http://php.net/manual/en/function.getcwd.php

__FILE__renverra le chemin avec le nom de fichier par exemple sur XAMPP C:\xampp\htdocs\index.phpau lieu deC:\xampp\htdocs\

pkarecki
la source
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/

Sultanos
la source
7

Utilisez simplement ci-dessous:

echo __DIR__;
Matricore
la source
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

minhajul
la source
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'])
SiteKickr
la source
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;
}
blizzrdof77
la source
1

essayez ceci sur votre script

echo getcwd() . "\n";
Shuhad zaman
la source
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.

Victor
la source
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']);
}
andrewniesen
la source
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.

Paolo
la source