Como incluir arquivos PHP que requerem um caminho absoluto?

95

Eu tenho uma estrutura de diretório como a seguinte;

script.php

inc / include1.php
inc / include2.php

objects / object1.php
objects / object2.php

soap / soap.php

Agora, eu uso esses objetos em ambos script.phpe /soap/soap.php, poderia movê-los, mas quero a estrutura de diretório assim por um motivo específico. Ao executar script.phpo caminho de inclusão inc/include.phpe, ao executá- /soap/soap.phplo ../inc, os caminhos absolutos funcionam, /mnt/webdev/[project name]/inc/include1.php...mas é uma solução feia se eu quiser mover o diretório para um local diferente.

Portanto, há uma maneira de usar caminhos relativos ou de gerar programaticamente o "/mnt/webdev/[project name]/"?

Xenph Yan
fonte

Respostas:

149

Isso deve funcionar

$root = realpath($_SERVER["DOCUMENT_ROOT"]);

include "$root/inc/include1.php";

Editar: aprimoramento adicionado por aussieviking

Peter Coulton
fonte
2
Tenha cuidado, isso só funcionará se você executar o script por meio de um servidor da web que o preencheDOCUMENT_ROOT
Phil
só uma pergunta, por que realpath () para $ _SERVER ["DOCUMENT_ROOT"]? Isso não deve gerar sempre o caminho canônico?
João Pimentel Ferreira
44

Você pode usar caminhos relativos. Experimente __FILE__. Esta é uma constante PHP que sempre retorna o caminho / nome do arquivo do script em que está. Portanto, em soap.php, você pode fazer:

include dirname(__FILE__).'/../inc/include.php';

O caminho completo e o nome do arquivo do arquivo. Se usado dentro de um include, o nome do arquivo incluído é retornado. Desde o PHP 4.0.2, __FILE__sempre contém um caminho absoluto com links simbólicos resolvidos, enquanto em versões anteriores continha um caminho relativo em algumas circunstâncias. (fonte)

Outra solução seria definir um caminho de inclusão em seu arquivo httpd.conf ou .htaccess.

Kevin
fonte
8
Acho que você deve adicionar um /no início da expressão entre aspas, para separar o ..do nome do FILE .
Dunaril
9
Note que desde o PHP 5.3.0 você pode usar a constante mágica __DIR__ao invés de ter que usar dirname(__FILE__). (Documentos PHP)
Erwin Wessels
3
include dirname(__FILE__).'/../inc/include.php';Não se esqueça do "/" antes do caminho relativo.
Steven Leimberg
6

Outra maneira de lidar com isso que elimina qualquer necessidade de inclusões é usar o recurso de carregamento automático. Incluir tudo o que seu script precisa "Just in Case" pode impedir o desempenho. Se as suas inclusões são todas as definições de classe ou interface e você deseja carregá-las apenas quando necessário, você pode sobrecarregar a __autoload()função com seu próprio código para encontrar o arquivo de classe apropriado e carregá-lo apenas quando for chamado. Aqui está o exemplo do manual:

function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

Contanto que você defina suas variáveis ​​include_path de acordo, você nunca precisará incluir um arquivo de classe novamente.

Sam McAfee
fonte
6

dê uma olhada em http://au.php.net/reserved.variables

Acho que a variável que você está procurando é: $_SERVER["DOCUMENT_ROOT"]

Christian Hagelid
fonte
5

Você pode definir uma constante com o caminho para o diretório raiz do seu projeto e, em seguida, colocá-la no início do caminho.

Ryan Fox
fonte
2

Outra opção, relacionada ao Kevin, é usar __FILE__, mas em vez disso, substituir o nome do arquivo php de dentro dele:

<?php

$docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__);
require_once($docRoot . '/lib/include.php');

?>

Estou usando isso há um tempo. O único problema é que às vezes você não tem $_SERVER['SCRIPT_NAME'], mas às vezes há outra variável semelhante.

Darryl Hein
fonte
2

Achei que isso funcionou muito bem!

function findRoot() { 
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

Usar:

<?php

function findRoot() {
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

include(findRoot() . 'Post.php');
$posts = getPosts(findRoot() . 'posts_content');

include(findRoot() . 'includes/head.php');

for ($i=(sizeof($posts)-1); 0 <= $i; $i--) {
    $posts[$i]->displayArticle();
}

include(findRoot() . 'includes/footer.php');

?>
Thane Gill
fonte
1

Acho que a melhor maneira é colocar suas inclusões no caminho de inclusão de PHP. Existem várias maneiras de fazer isso, dependendo de sua configuração.

Então você pode simplesmente se referir a

require_once 'inc1.php';

de dentro de qualquer arquivo, independentemente de onde ele esteja, seja em seus arquivos incluídos ou acessíveis na web, ou em qualquer nível de subdiretórios aninhados.

Isso permite que você inclua arquivos fora da raiz do servidor da web, o que é uma prática recomendada.

por exemplo

site directory
    html (web root)
        your web-accessible files
    includes
        your include files

Além disso, verifique __autoload para carregamento lento de arquivos de classe

http://www.google.com/search?q=setting+php+include+path

http://www.google.com/search?q=__autoload

Polsonby
fonte
1
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php");

Eu uso esta linha de código. Ele volta para o "topo" da árvore do site e depois vai para o arquivo desejado.

Por exemplo, digamos que eu tenha esta árvore de arquivos:

domain.com/aaa/index.php
domain.com/bbb/ccc/ddd/index.php
domain.com/_resources/functions.php

Posso incluir o arquivo functions.php de qualquer lugar, apenas copiando e colando

require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/_resources/functions.php");

Se você precisar usar este código muitas vezes, pode criar uma função que retorna a str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))parte. Em seguida, basta inserir esta função no primeiro arquivo que você incluir. Eu tenho um arquivo "initialize.php" que incluo no topo de cada página php e que contém essa função. Na próxima vez que tiver que incluir arquivos, na verdade, apenas uso a função (nomeada path_back):

require(path_back()."/_resources/another_php_file.php");
Machavity
fonte
0

@Flubba, isso me permite ter pastas dentro do meu diretório de inclusão? os diretórios de inclusão plana me dão pesadelos. já que todo o diretório de objetos deve estar no diretório inc.

Oh sim, absolutamente. Por exemplo, usamos uma única camada de subpastas, geralmente:

require_once('library/string.class.php')

Você precisa ter cuidado ao confiar muito no caminho de inclusão em sites de muito tráfego, porque o php tem que procurar no diretório atual e em todos os diretórios no caminho de inclusão para ver se seu arquivo está lá e isso pode ficar lento coisas se você está sendo martelado.

Então, por exemplo, se você estiver fazendo MVC, você colocaria o caminho para o diretório do seu aplicativo no caminho de inclusão e, em seguida, especificaria referir-se a coisas no formulário

'model/user.class'
'controllers/front.php'

como queiras.

Mas, de modo geral, ele permite que você trabalhe com caminhos realmente curtos em seu PHP que funcionarão de qualquer lugar e é muito mais fácil de ler do que toda aquela malarkey raiz de documento de caminho real.

O benefício dessas alternativas baseadas em script que outros sugeriram é que elas funcionam em qualquer lugar, mesmo em caixas compartilhadas; definir o caminho de inclusão requer um pouco mais de reflexão e esforço, mas como mencionei, permite que você comece a usar __autoload, que é apenas o mais legal.

Polsonby
fonte
0

Se você for incluir um caminho específico na maioria dos arquivos em seu aplicativo, crie uma variável Global para sua pasta raiz.

define("APPLICATION_PATH", realpath(dirname(__FILE__) . '/../app'));
or 
define("APPLICATION_PATH", realpath(DIR(__FILE__) . '/../app'));

Agora, esta variável global " APPLICATION_PATH " pode ser usada para incluir todos os arquivos ao invés de chamar realpath () toda vez que você incluir um novo arquivo.

EX:

include(APPLICATION_PATH ."/config/config.ini";

Espero que ajude ;-)

Yuvraj
fonte