Obter caminho absoluto do script executado inicialmente

247

Eu pesquisei alto e baixo e obtive muitas soluções e variáveis ​​diferentes contendo informações para obter o caminho absoluto. Mas eles parecem funcionar sob algumas condições e não sob outras. Existe uma maneira de obter o caminho absoluto do script executado no PHP? Para mim, o script será executado a partir da linha de comando, mas uma solução deve funcionar tão bem se executada no Apache etc.

Esclarecimento: O script executado inicialmente, não necessariamente o arquivo em que a solução está codificada.

inquirir
fonte
verdade mesmo mathheadinclouds. Eu aceitei isso há muito tempo, quando eu tinha apenas um script e funcionou para mim. Eu removi a resposta aceita para deixar claro que não resolve o problema inicial. Armazenar a constante FILE quando a execução começa em um script é um caminho a percorrer, mas longe do ideal.
Inquam
solicitado script é o que você queria, script atual = com este código solução
Bitterblue

Respostas:

33

A solução correta é usar a get_included_filesfunção:

list($scriptPath) = get_included_files();

Isso fornecerá o caminho absoluto do script inicial, mesmo que:

  • Esta função é colocada dentro de um arquivo incluído
  • O diretório de trabalho atual é diferente do diretório do script inicial
  • O script é executado com a CLI, como um caminho relativo

Aqui estão dois scripts de teste; o script principal e um arquivo incluído:

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

E o resultado; observe o diretório atual:

C:\>php C:\Users\Redacted\Desktop\main.php
The script being executed is C:\Users\Redacted\Desktop\main.php
Salman A
fonte
Essa solução funciona, mas vale a pena mencionar que, lendo a documentação , não há menção de que o caminho do script executado inicialmente seja o primeiro item da matriz retornada por get_included_files(). Eu sugiro a loja __FILE__em uma constante no início do script feito para ser executado inicialmente.
Paolo
270

__FILE__ constante fornecerá o caminho absoluto para o arquivo atual.

Atualização :

A pergunta foi alterada para perguntar como recuperar o script executado inicialmente em vez do script em execução no momento. A única maneira confiável de fazer isso é usar a debug_backtracefunção

$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];
zerkms
fonte
Se eu estiver usando um padrão de controle frontal. Iria __FILE__retornar a localização do index.php ou a localização do arquivo incluído? Como obteria a localização do index.php?
CMCDragonkai
Bem __FILE__aponta para o caminho do script atual. Mas não encontrei nada para mostrar o caminho atual do index.php.
CMCDragonkai
1
@CMCDragonkai: faça uma pergunta em separado, então #
zerkms
2
CUIDADO: se o script estiver em um diretório virtual apache2, as informações retornadas NÃO fornecerão o local do caminho real no servidor físico. Eu queria isso para fins de depuração, e mesmo as variáveis ​​$ _SERVER não fornecem isso. Por exemplo, se index.php existir em / var / www / vpath1 / html e / var / www / html / e / var / www / vpath2 / html, e cada um deles estiver virtualmente mapeado para / var / www / html, então / var / www / html é o que você verá, independentemente do servidor virtual usado.
22614 Mark Richards
1
@ChristofferBubach, você nem precisa jogá-lo: um objeto de exceção coleta o rastreamento da pilha durante a construção.
zerkms
262

A resposta foi movida para aqui - https://stackoverflow.com/a/26944636/2377343

T.Todua
fonte
1
obter a pasta atual do scriptstr_replace( basename(__FILE__) , '',str_replace($_SERVER["DOCUMENT_ROOT"],'',str_replace('\\','/',__FILE__ ) ) ) === /folder1/folder2/
Salem
2
Essa é de longe a lista mais abrangente de exemplos de maneiras de obter parte ou todo o caminho do arquivo que eu já vi em toda a Internet.
Sean the Bean
241
echo realpath(dirname(__FILE__));

Se você colocar isso em um arquivo incluído, ele imprimirá o caminho para essa inclusão. Para obter o caminho do script pai, substitua __FILE__por $_SERVER['PHP_SELF']. Mas esteja ciente de que o PHP_SELF é um risco à segurança!

rik
fonte
1
Era exatamente isso que eu queria
pergunte
13
qual é a utilidade do caminho real aqui?
Seu senso comum
11
@Col. Shrapnel: "Desde o PHP 4.0.2, __FILE__sempre contém um caminho absoluto com links simbólicos resolvidos, enquanto nas versões mais antigas ele continha um caminho relativo em algumas circunstâncias." plus "dirname () opera ingenuamente na string de entrada e não está ciente do sistema de arquivos real ou dos componentes do caminho como '..'. '
rik
6
ah, 4.0.2. Século passado?
Seu senso comum
2
@ rik: também, que problema de segurança pode causar PHP_SELF?
Zerkms
38
__DIR__

Do manual :

O diretório do arquivo. Se usado dentro de uma inclusão, o diretório do arquivo incluído é retornado. Isso é equivalente a dirname(__FILE__). Esse nome de diretório não possui uma barra final, a menos que seja o diretório raiz.
__FILE__ sempre contém um caminho absoluto com links simbólicos resolvidos, enquanto nas versões mais antigas (que 4.0.2) ele continha um caminho relativo em algumas circunstâncias.

Nota : __DIR__foi adicionado no PHP 5.3.0.

Gottlieb Notschnabel
fonte
21

Se você deseja obter o diretório de trabalho atual, usegetcwd()

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

__FILE__retornará o caminho com o nome do arquivo, por exemplo, no XAMPP, em C:\xampp\htdocs\index.phpvez deC:\xampp\htdocs\

pkarecki
fonte
8
dirname(__FILE__) 

fornecerá a rota absoluta do arquivo atual do qual você está exigindo a rota, a rota do diretório do servidor.

arquivos de exemplo:

www / http / html / index.php; se você colocar esse código dentro do seu index.php, ele retornará:

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

www / http / html / class / myclass.php; se você colocar esse código dentro do myclass.php, ele retornará:

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

Sultanos
fonte
7

Basta usar abaixo:

echo __DIR__;
Matricore
fonte
1
Sry, a idéia é obter o primeiro script acionado ... Não é o que você está agora. Portanto, uma árvore de inclusão de a.php->b.php->c.phpdeve ser o caminho de a.php se marcada em c.php . A única maneira que parece confiável é usar a função debug_backtrace () .
Inquam
5
`realpath(dirname(__FILE__))` 

fornece o diretório de script atual (o script no qual você colocou esse código) sem barra final. isso é importante se você deseja incluir outros arquivos com o resultado

minhajul
fonte
Sim, mas a idéia é ser capaz de obter o caminho absoluto para o "script de disparo" A.php, mesmo dentro do B.php, se isso estiver incluído no A.php. PODE, é claro, ser feito armazenando o script inicial para acesso posterior, mas a questão era se é possível obtê-lo sem fazer isso.
Inquam
4

Se você está procurando o caminho absoluto em relação à raiz do servidor, descobri que isso funciona bem:

$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])
SiteKickr
fonte
Quando eu estava checando essa solução em diferentes servidores, ela sempre me dava o caminho com o Linux como separadores de diretórios, independentemente do sistema operacional do host (Windows e Linux). Para mim isso é uma vantagem.
Bronek
3

Aqui está uma função PHP útil que escrevi para isso com precisão. Como a pergunta original esclarece, ela retorna o caminho a partir do qual o script inicial foi executado - e não o arquivo em que estamos atualmente.

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

tente isso no seu script

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

Para o script executado no servidor da web $_SERVER['SCRIPT_FILENAME'], o caminho completo para o script inicialmente chamado será contido, provavelmente o seu index.php. realpath()não é necessário neste caso.

Para o script, a execução no console $_SERVER['SCRIPT_FILENAME']conterá um caminho relativo para o script inicialmente chamado do seu diretório de trabalho atual. Portanto, a menos que você altere o diretório de trabalho dentro do seu script, ele será resolvido para o caminho absoluto.

Vencedor
fonte
1

É isso que eu uso e funciona em ambientes Linux. Eu não acho que isso funcionaria em uma máquina 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
fonte
1

Uma maneira simples de ter o caminho absoluto do roteiro executada inicialmente , em que o script e qualquer outro script incluído com include, require, require_onceé usando um constante e armazenar lá o caminho do script atual no início do script principal :

define( 'SCRIPT_ROOT', __FILE__ );

A solução acima é adequada quando existe um único script "principal" que includeé todo script necessário, como na maioria dos aplicativos da Web.

Se esse não for o caso, e pode haver vários "scripts intitais", para evitar redefinições e ter o caminho correto armazenado dentro da constante em que cada script pode começar:

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

Uma observação sobre a resposta (atualmente) aceita :

a resposta afirma que o caminho do script executado inicialmente é o primeiro elemento da matriz retornado por get_included_files() .

Esta é uma solução inteligente e simples e, no momento da escrita, (estamos quase no PHP 7.4.0), ela funciona .

No entanto, observando a documentação, não há menção de que o script inicialmente executado seja o primeiro item da matriz retornada por get_included_files().

Nós lemos apenas

O script originalmente chamado é considerado um "arquivo incluído", portanto será listado junto com os arquivos referenciados por include e family.

No momento da escrita, o " script originalmente chamado " é o primeiro da matriz, mas - tecnicamente - não há garantia de que isso não mude no futuro.


A cerca de nota realpath(), __FILE__e __DIR__:

Outros sugeriram em suas respostas o uso de __FILE__, __DIR__, dirname(__FILE__), realpath(__DIR__)...

dirname(__FILE__)é igual a __DIR__(introduzido no PHP 5.3.0), então apenas use __DIR__.

Ambos __FILE__e __DIR__sempre são caminhos absolutos, por isso realpath()é desnecessário.

Paolo
fonte