Holen Sie sich den absoluten Pfad des ursprünglich ausgeführten Skripts


247

Ich habe hoch und niedrig gesucht und viele verschiedene Lösungen und Variablen mit Informationen erhalten, um den absoluten Pfad zu erhalten. Aber sie scheinen unter bestimmten Bedingungen zu funktionieren und unter anderen nicht. Gibt es eine Möglichkeit, den absoluten Pfad des ausgeführten Skripts in PHP zu ermitteln? Für mich wird das Skript über die Befehlszeile ausgeführt, aber eine Lösung sollte genauso gut funktionieren, wenn sie in Apache usw. ausgeführt wird.

Erläuterung: Das ursprünglich ausgeführte Skript, nicht unbedingt die Datei, in der die Lösung codiert ist.


wahr in der Tat Mathheadinclouds. Ich habe es vor langer Zeit akzeptiert, als ich nur ein Skript hatte und es für mich funktionierte. Ich habe die akzeptierte Antwort entfernt, um zu verdeutlichen, dass das ursprüngliche Problem dadurch nicht gelöst wird. Das Speichern der FILE-Konstante, wenn die Ausführung in einem Skript beginnt, ist eine Möglichkeit, aber alles andere als ideal.
Anfrage

angefordertes Skript ist das, was Sie wollten, aktuelles Skript = mit diesem
Lösungscode

Antworten:


33

Die richtige Lösung besteht darin, die get_included_filesFunktion zu verwenden:

list($scriptPath) = get_included_files();

Dies gibt Ihnen den absoluten Pfad des ursprünglichen Skripts, auch wenn:

  • Diese Funktion befindet sich in einer enthaltenen Datei
  • Das aktuelle Arbeitsverzeichnis unterscheidet sich vom Verzeichnis des ursprünglichen Skripts
  • Das Skript wird mit der CLI als relativem Pfad ausgeführt

Hier sind zwei Testskripte; das Hauptskript und eine enthaltene Datei:

# 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;
}

Und das Ergebnis; Beachten Sie das aktuelle Verzeichnis:

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

Diese Lösung funktioniert, aber es ist erwähnenswert, dass beim Lesen der Dokumentation nicht erwähnt wird, dass der Pfad des ursprünglich ausgeführten Skripts das erste Element des Arrays ist, das von zurückgegeben wird get_included_files(). Ich schlage vor , __FILE__am Anfang des Skripts eine Konstante zu speichern , die ursprünglich ausgeführt werden soll.
Paolo

270

__FILE__ Konstante gibt Ihnen den absoluten Pfad zur aktuellen Datei.

Update :

Die Frage wurde geändert, um zu fragen, wie das ursprünglich ausgeführte Skript anstelle des aktuell ausgeführten Skripts abgerufen werden kann. Der einzige (??) zuverlässige Weg, dies zu tun, ist die Verwendung der debug_backtraceFunktion.

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

Wenn ich ein Front-Controller-Muster verwende. Würde __FILE__der Speicherort der index.php oder der Speicherort der enthaltenen Datei zurückgegeben? Wie würde ich den Speicherort der index.php ermitteln?
CMCDragonkai

Nun __FILE__zeigt auf den Pfad des aktuellen Skripts. Aber ich habe nichts gefunden, was den Pfad der aktuellen index.php anzeigt.
CMCDragonkai

1
@CMCDragonkai: Stellen Sie dann eine separate Frage
zerkms

2
VORSICHT: Wenn sich das Skript in einem virtuellen Apache2-Verzeichnis befindet, geben die zurückgegebenen Informationen NICHT den tatsächlichen Pfad auf dem physischen Server an. Ich wollte dies für Debug-Zwecke, und selbst die $ _SERVER-Variablen bieten dies nicht. Wenn beispielsweise index.php in / var / www / vpath1 / html und / var / www / html / und / var / www / vpath2 / html vorhanden ist und jede dieser Dateien virtuell / var / www / html zugeordnet ist, Dann sehen Sie / var / www / html, egal welcher virtuelle Server verwendet wird.
Mark Richards

1
@ChristofferBubach Sie müssen es nicht einmal werfen: Ein Ausnahmeobjekt sammelt die Stapelverfolgung während der Erstellung.
Zerkms

262

Die Antwort wurde hierher verschoben - https://stackoverflow.com/a/26944636/2377343


1
um den aktuellen Ordner des Skripts zu erhaltenstr_replace( basename(__FILE__) , '',str_replace($_SERVER["DOCUMENT_ROOT"],'',str_replace('\\','/',__FILE__ ) ) ) === /folder1/folder2/
Salem

2
Dies ist bei weitem die umfassendste Liste von Beispielen, wie Sie einen Teil oder den gesamten Dateipfad abrufen können, den ich im gesamten Internet gesehen habe.
Sean the Bean

241
echo realpath(dirname(__FILE__));

Wenn Sie dies in eine eingeschlossene Datei einfügen, wird der Pfad zu diesem Include gedruckt. Ersetzen Sie __FILE__durch, um den Pfad des übergeordneten Skripts abzurufen $_SERVER['PHP_SELF']. Beachten Sie jedoch, dass PHP_SELF ein Sicherheitsrisiko darstellt!


1
Dies war genau das, was ich wollte
erkundigen Sie sich am

13
Was nützt Realpath hier?
Ihr gesunder Menschenverstand

11
@Col. Shrapnel: "Seit PHP 4.0.2 __FILE__enthält es immer einen absoluten Pfad mit aufgelösten Symlinks, während es in älteren Versionen unter bestimmten Umständen einen relativen Pfad enthielt." plus "dirname () arbeitet naiv mit der Eingabezeichenfolge und kennt weder das eigentliche Dateisystem noch Pfadkomponenten wie '..'.
rik

6
oh, 4.0.2. Letztes Jahrhundert?
Ihr gesunder Menschenverstand

2
@rik: auch, welches Sicherheitsproblem kann verursachen PHP_SELF?
Zerkms

38
__DIR__

Aus dem Handbuch :

Das Verzeichnis der Datei. Bei Verwendung in einem Include wird das Verzeichnis der enthaltenen Datei zurückgegeben. Dies entspricht dirname(__FILE__). Dieser Verzeichnisname hat keinen abschließenden Schrägstrich, es sei denn, es handelt sich um das Stammverzeichnis.
__FILE__ enthält immer einen absoluten Pfad mit aufgelösten Symlinks, während er in älteren Versionen (als 4.0.2) unter bestimmten Umständen einen relativen Pfad enthielt.

Hinweis : __DIR__wurde in PHP 5.3.0 hinzugefügt.



8
dirname(__FILE__) 

gibt die absolute Route der aktuellen Datei an, von der Sie die Route anfordern, die Route Ihres Serververzeichnisses.

Beispieldateien:

www / http / html / index.php; Wenn Sie diesen Code in Ihre index.php einfügen, wird Folgendes zurückgegeben:

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

www / http / html / class / myclass.php; Wenn Sie diesen Code in Ihre myclass.php einfügen, wird Folgendes zurückgegeben:

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


7

Verwenden Sie einfach unten:

echo __DIR__;

1
Sry, die Idee ist, das erste abgefeuerte Skript zu bekommen ... Nicht das, in dem du gerade bist. Ein Einschlussbaum von a.php->b.php->c.phpsollte also der Pfad von a.php sein, wenn er in c.php aktiviert ist . Der einzige Weg, der zuverlässig zu sein scheint, ist die Verwendung der Funktion debug_backtrace () .
Anfrage

5
`realpath(dirname(__FILE__))` 

Es gibt Ihnen das aktuelle Skriptverzeichnis (das Skript, in das Sie diesen Code eingefügt haben) ohne abschließenden Schrägstrich. Dies ist wichtig, wenn Sie andere Dateien in das Ergebnis aufnehmen möchten


Ja, aber die Idee ist, den absoluten Pfad zum "Feuerskript" A.php auch innerhalb von B.php zu erhalten, wenn dies in A.php enthalten ist. Dies kann oder kann durch Speichern des ursprünglichen Skripts für den späteren Zugriff erfolgen, aber die Frage war, ob es möglich ist, es zu erhalten, ohne dies zu tun.
Anfrage

4

Wenn Sie nach dem absoluten Pfad relativ zum Serverstamm suchen, habe ich festgestellt, dass dies gut funktioniert:

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

Wenn ich diese Lösung mit verschiedenen Servern verglich, gab sie mir immer einen Pfad mit Linux-ähnlichen Trennzeichen, unabhängig vom Betriebssystem des Hosts (Windows und Linux). Für mich ist das ein Vorteil.
Bronek

3

Hier ist eine nützliche PHP-Funktion, die ich genau dafür geschrieben habe. Wie die ursprüngliche Frage klarstellt, gibt sie den Pfad zurück, von dem aus das ursprüngliche Skript ausgeführt wurde - nicht die Datei, in der wir uns gerade befinden.

/**
 * 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'])

Für Skripte, die unter einem Webserver ausgeführt $_SERVER['SCRIPT_FILENAME']werden, enthält der vollständige Pfad zum ursprünglich aufgerufenen Skript, also wahrscheinlich Ihre index.php. realpath()ist in diesem Fall nicht erforderlich.

Das Skript, das von der Konsole ausgeführt $_SERVER['SCRIPT_FILENAME']wird, enthält einen relativen Pfad zu Ihrem ursprünglich aufgerufenen Skript aus Ihrem aktuellen Arbeitsverzeichnis. Wenn Sie also das Arbeitsverzeichnis in Ihrem Skript nicht geändert haben, wird es in den absoluten Pfad aufgelöst.


1

Dies ist, was ich benutze und es funktioniert in Linux-Umgebungen. Ich glaube nicht, dass dies auf einem Windows-Computer funktionieren würde ...

//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

Ein einfacher Weg , um den absoluten Pfad des haben anfänglich ausgeführte Skript , in dem Skript und jeder anderen Skript enthielt mit include, require, require_onceist durch Verwendung eines konstanten und da den aktuellen Skript Pfades Speicherung des am Anfang Hauptskript :

define( 'SCRIPT_ROOT', __FILE__ );

Die obige Lösung ist geeignet, wenn es ein einziges "Hauptskript" gibt, das includejedes andere benötigte Skript enthält, wie in den meisten Webanwendungen.

Wenn dies nicht der Fall ist und es möglicherweise mehrere "Intital-Skripte" gibt, kann jedes Skript beginnen, um Neudefinitionen zu vermeiden und den richtigen Pfad in der Konstante zu speichern:

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

Ein Hinweis zur (derzeit) akzeptierten Antwort :

Die Antwort besagt, dass der ursprünglich ausgeführte Skriptpfad das erste Element des von zurückgegebenen Arrays ist get_included_files().

Dies ist eine clevere und einfache Lösung, die zum Zeitpunkt des Schreibens (wir sind fast bei PHP 7.4.0) funktioniert .

In der Dokumentation wird jedoch nicht erwähnt, dass das ursprünglich ausgeführte Skript das erste Element des von zurückgegebenen Arrays ist get_included_files().

Wir lesen nur

Das ursprünglich aufgerufene Skript wird als "eingeschlossene Datei" betrachtet, daher wird es zusammen mit den Dateien aufgelistet, auf die include und family verweisen.

Zum Zeitpunkt des Schreibens ist das " ursprünglich aufgerufene Skript " das erste im Array, aber technisch gesehen gibt es keine Garantie dafür, dass sich dies in Zukunft nicht ändern wird.


Ein Hinweis zu realpath(), __FILE__und __DIR__:

Andere haben in ihren Antworten die Verwendung vorgeschlagen __FILE__, __DIR__, dirname(__FILE__), realpath(__DIR__)...

dirname(__FILE__)ist gleich __DIR__(eingeführt in PHP 5.3.0), also einfach verwenden __DIR__.

Beide __FILE__und __DIR__sind immer absolute Pfade , realpath()ist also unnötig.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.