Obtenga la ruta absoluta del script ejecutado inicialmente

247

He buscado arriba y abajo y obtengo muchas soluciones y variables diferentes que contienen información para obtener la ruta absoluta. Pero parecen funcionar en algunas condiciones y no en otras. ¿Hay una forma de bala de plata para obtener la ruta absoluta del script ejecutado en PHP? Para mí, el script se ejecutará desde la línea de comandos, pero una solución debería funcionar igual de bien si se ejecuta dentro de Apache, etc.

Aclaración: El script ejecutado inicialmente, no necesariamente el archivo donde se codifica la solución.

inquam
fuente
cierto de hecho mathheadinclouds. Lo acepté hace mucho tiempo cuando solo tenía un guión y funcionó para mí. Eliminé la respuesta aceptada para dejar en claro que no resuelve el problema inicial. Almacenar la constante FILE cuando la ejecución comienza en un script es un camino a seguir, pero lejos de ser ideal.
pregunte el
el script solicitado es lo que quería, el script actual = con este código de solución
Bitterblue

Respuestas:

33

La solución correcta es usar la get_included_filesfunción:

list($scriptPath) = get_included_files();

Esto le dará la ruta absoluta de la secuencia de comandos inicial, incluso si:

  • Esta función se coloca dentro de un archivo incluido
  • El directorio de trabajo actual es diferente del directorio del script inicial
  • El script se ejecuta con la CLI, como una ruta relativa

Aquí hay dos scripts de prueba; El guión principal y un archivo incluido:

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

Y el resultado; observe el directorio actual:

C:\>php C:\Users\Redacted\Desktop\main.php
The script being executed is C:\Users\Redacted\Desktop\main.php
Salman A
fuente
Esta solución funciona, pero vale la pena mencionar que, al leer la documentación , no se menciona que la ruta del script ejecutado inicialmente es el primer elemento de la matriz devuelto por get_included_files(). Yo sugiero a la tienda __FILE__en una constante en el comienzo de la secuencia de comandos destinado a ser ejecutado inicialmente.
Paolo
270

__FILE__ constante le dará la ruta absoluta al archivo actual.

Actualización :

La pregunta se cambió para preguntar cómo recuperar el script ejecutado inicialmente en lugar del script actualmente en ejecución. La única (??) forma confiable de hacerlo es usar la debug_backtracefunción.

$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];
zerkms
fuente
Si estoy usando un patrón de controlador frontal. ¿ __FILE__Devolvería la ubicación de index.php o la ubicación del archivo incluido? ¿Cómo obtendría la ubicación de index.php?
CMCDragonkai
Bien __FILE__apunta a la ruta del script actual. Pero no he encontrado nada que muestre la ruta actual de index.php.
CMCDragonkai
1
@CMCDragonkai: haga una pregunta por separado entonces
zerkms
2
PRECAUCIÓN: si el script está en un directorio virtual apache2, la información devuelta NO proporciona la ubicación de la ruta real en el servidor físico. Quería esto para fines de depuración, e incluso las variables $ _SERVER no proporcionan esto. Por ejemplo, si index.php existe en / var / www / vpath1 / html y / var / www / html / y / var / www / vpath2 / html, y cada uno de ellos está virtualmente asignado a / var / www / html, entonces / var / www / html es lo que verá, sin importar qué servidor virtual se use.
Mark Richards
1
@ChristofferBubach ni siquiera necesita tirarlo: un objeto de excepción recoge el rastro de la pila durante la construcción.
zerkms
262

La respuesta se ha movido aquí: https://stackoverflow.com/a/26944636/2377343

T.Todua
fuente
1
obtener la carpeta actual del scriptstr_replace( basename(__FILE__) , '',str_replace($_SERVER["DOCUMENT_ROOT"],'',str_replace('\\','/',__FILE__ ) ) ) === /folder1/folder2/
Salem
2
Esta es, con mucho, la lista más completa de ejemplos de formas de obtener parte o la totalidad de la ruta del archivo que he visto en Internet.
Sean the Bean
241
echo realpath(dirname(__FILE__));

Si coloca esto en un archivo incluido, imprime la ruta a esta inclusión. Para obtener la ruta del script principal, reemplace __FILE__con $_SERVER['PHP_SELF']. ¡Pero tenga en cuenta que PHP_SELF es un riesgo de seguridad!

rik
fuente
1
Esto fue exactamente lo que quería
Inquam
13
¿Cuál es el uso de Realpath aquí?
Su sentido común el
11
@Columna. Metralla: "Desde PHP 4.0.2, __FILE__siempre contiene una ruta absoluta con enlaces simbólicos resueltos, mientras que en versiones anteriores contenía una ruta relativa en algunas circunstancias". más "dirname () opera ingenuamente en la cadena de entrada, y no conoce el sistema de archivos real o los componentes de ruta como '..'.
rik
66
oh, 4.0.2. Siglo pasado?
Su sentido común el
2
@rik: también, ¿qué problema de seguridad puede causar PHP_SELF?
zerkms
38
__DIR__

Del manual :

El directorio del archivo. Si se usa dentro de un include, se devuelve el directorio del archivo incluido. Esto es equivalente a dirname(__FILE__). Este nombre de directorio no tiene una barra inclinada final a menos que sea el directorio raíz.
__FILE__ siempre contiene una ruta absoluta con enlaces simbólicos resueltos, mientras que en versiones anteriores (que 4.0.2) contenía una ruta relativa en algunas circunstancias.

Nota : __DIR__se agregó en PHP 5.3.0.

Gottlieb Notschnabel
fuente
21

Si quieres obtener el directorio de trabajo actual, usegetcwd()

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

__FILE__devolverá la ruta con el nombre del archivo, por ejemplo, en XAMPP en C:\xampp\htdocs\index.phplugar deC:\xampp\htdocs\

pkarecki
fuente
8
dirname(__FILE__) 

dará la ruta absoluta del archivo actual desde el que solicita la ruta, la ruta del directorio de su servidor.

archivos de ejemplo:

www / http / html / index.php; si coloca este código dentro de su index.php devolverá:

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

www / http / html / class / myclass.php; si coloca este código dentro de su myclass.php devolverá:

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

Sultanos
fuente
7

Solo use a continuación:

echo __DIR__;
Matricore
fuente
1
Sry, la idea es obtener el primer guión disparado ... No en el que estás ahora. Entonces, un árbol de inclusión de a.php->b.php->c.phpdebería ser la ruta de a.php si se marca en c.php . La única forma que parece ser confiable es usar la función debug_backtrace () .
consulta el
5
`realpath(dirname(__FILE__))` 

le da el directorio actual del script (el script dentro del cual colocó este código) sin barra diagonal final. Esto es importante si desea incluir otros archivos con el resultado

minhajul
fuente
Sí, pero la idea es poder obtener el camino absoluto hacia el "script de disparo" A.php incluso dentro de B.php si eso está incluido por A.php. Se PUEDE hacer, por supuesto, almacenando el script inicial para un acceso posterior, pero la pregunta era si es posible obtenerlo sin hacerlo.
inquam
4

Si está buscando la ruta absoluta relativa a la raíz del servidor, descubrí que esto funciona bien:

$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])
SiteKickr
fuente
Cuando estaba comprobando esta solución en diferentes servidores, siempre me daba la ruta con Linux como separadores de directorios, independientemente del sistema operativo del host (Windows y Linux). Para mí eso es una ventaja.
Bronek
3

Aquí hay una útil función PHP que escribí para esto precisamente. Como aclara la pregunta original, devuelve la ruta desde la que se ejecutó el script inicial , no el archivo en el que estamos actualmente.

/**
 * 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
fuente
1

prueba esto en tu script

echo getcwd() . "\n";
Shuhad Zaman
fuente
1
realpath($_SERVER['SCRIPT_FILENAME'])

Para la secuencia de comandos ejecutada en el servidor web $_SERVER['SCRIPT_FILENAME']contendrá la ruta completa a la secuencia de comandos inicialmente llamada, por lo que probablemente su index.php.realpath()No es necesario en este caso.

Para el script ejecutado desde la consola $_SERVER['SCRIPT_FILENAME'], contendrá la ruta relativa a su script inicialmente llamado desde su directorio de trabajo actual. Entonces, a menos que haya cambiado el directorio de trabajo dentro de su script, se resolverá en la ruta absoluta.

Víctor
fuente
1

Esto es lo que uso y funciona en entornos Linux. No creo que esto funcione en una máquina con 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
fuente
1

Una manera simple de tener la ruta absoluta del guión inicialmente ejecutado , en esa secuencia de comandos y cualquier otra secuencia de comandos se incluye con include, require, require_oncees mediante el uso de una constante y almacenar allí la ruta del script actual al inicio del script principal :

define( 'SCRIPT_ROOT', __FILE__ );

La solución anterior es adecuada cuando hay un solo script "principal" que includees cualquier otro script necesario, como en la mayoría de las aplicaciones web.

Si ese no es el caso y puede haber varios "guiones iniciales", para evitar redefiniciones y tener la ruta correcta almacenada dentro de la constante, cada guión puede comenzar con:

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

Una nota sobre la respuesta (actualmente) aceptada :

la respuesta indica que la ruta de script ejecutada inicialmente es el primer elemento de la matriz devuelta por get_included_files() .

Esta es una solución inteligente y simple y, al momento de escribir, (estamos casi en PHP 7.4.0) funciona .

Sin embargo, al mirar la documentación no se menciona que el script ejecutado inicialmente es el primer elemento de la matriz devuelto porget_included_files() .

Solo leemos

El script llamado originalmente se considera un "archivo incluido", por lo que se enumerará junto con los archivos a los que hace referencia include y family.

Al momento de escribir, el " script originalmente llamado " es el primero en la matriz pero, técnicamente , no hay garantía de que esto no cambie en el futuro.


Una nota acerca realpath(), __FILE__y __DIR__:

Otros han sugerido en sus respuestas al uso de __FILE__, __DIR__, dirname(__FILE__), realpath(__DIR__)...

dirname(__FILE__)es igual a __DIR__(introducido en PHP 5.3.0), así que solo use__DIR__ .

Ambos __FILE__y __DIR__siempre son caminos absolutos, por lo que realpath()es innecesario.

Paolo
fuente