Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa tarde galera, sou novo aqui mas já sei o básico de php.
Gostaria de saber uma coisa, a função include() do php, pode incluir arquivo através de um caminho "alternativo"?
Por exemplo, tenho um index.php no diretório "/site/pagina/" (raiz, depois pasta "site" e em seguida pasta "pagina").
Quero incluir nessa página um arquivo do diretório "/site/includes/", mas sem utilizar o ".." para voltar, isso é, utilizando uma variável global, que independente do diretório que eu esteja, o caminho para inclusão seja o mesmo.
Consigo fazer isso com images, por exemplo, mas a função do include pelo que entendi não aceita isso.
Segue um exemplo do código:
<?php
$DOCUMENT_ROOT = "/site"; (para voltar na raiz, e entrar na pasta do site)
include($DOCUMENT_ROOT."/includes/arquivo.php");
?>
O erro:
Warning: include(/site/includes/arquivo.php) [function.include]: failed to open stream: No such file or directory in C:\xampp\htdocs\site\paginas\index.php on line XX
OBS.:
¹ O caminho está correto, já verifiquei isso.
² Acredito que o problema seja na sintaxe, não sei se há essa possibilidade de não "percorrer" pelo site.
³ Os dados são fictícios, só quero saber se essa função da suporte a utilizar "url base" para incluir.
Desde já agradeço,
Matheus.
>
O problema é o SO. O Windows não aceita caminhos dessa forma.
"Dessa forma" que você diz, é iniciando com barra, como no unix?
Se for isso, aceita sim.
Inclusive, estou com 3 projetos locais aqui abertos que funcionam nesta estrutura (rodando em Win 7 + Apache 2 + PHP 5.3).
A unica diferença, é que fica ligeiramente mais lento para resolução (quase imperceptível), mas funciona sim.
O erro apresentado lá pelo @Maghost é de resolução de caminho. O arquivo não existe no caminho especificado.
Arquivo que ele tentou recuperar:
/site/includes/arquivo.php
Este é o caminho absoluto, mesma coisa que "C:\site\includes\arquivo.php", por conta da barra no inicio do nome do arquivo.
Arquivo que tentou incluir o anterior:
C:\xampp\htdocs\site\paginas\index.php
Veja que o caminho raiz é totalmente diferente: c:\xamp\htdocs
Logo, a solução postada pelo @Henrique vai funcionar, porque o dirname(__FILE__), como já explicado, recupera o diretório onde reside o arquivo da constante mágica __FILE__. Logo, seria algo como "C:\xampp\htdocs\site" e não "/site".
abs
"Dessa forma" que você diz, é iniciando com barra, como no unix?
Acho que, o que ele quis dizer, a princípio, é que:
quando se inclui um arquivo utilizando o caminho relativo para o arquivo que está sendo incluindo, não funciona em servidores windows.
Ficou confuso, certo?
Exemplo prático.
Seria mais ou menos assim. Possuo 3 arquivos na seguinte arquitetura de pastas (meramente ilustrativo).
/index.php
/autenticacao/login.php
/class/database.php
O relacionamento seria.:
index.php -> login.php
login.php -> database.php
O correto, ou diria, "intuitivo". Seria referenciar cada arquivo pela relação dele com o próximo:
index.php
include("autenticacao/login.php");
login.php
include("../class/database.php");
Os caminhos são relativos ao arquivo que está incluindo o próximo arquivo.
Entretanto, servidor windows não suporta assim. Os caminhos devem ser absolutos ou como referência o arquivo chamado pela URL (o primeiro executado). Nesse caso, index.php.
Então, para o servidor windows, teria de ser o seguinte:
index.php
include("autenticacao/login.php");
login.php
include("class/database.php");
Já no windows, os caminhos para a inclusão, são relativas ao arquivo "origem". O que está sendo chamado pela URL.
O que é bem chato de se trabalhar/pensar
O problema é o SO. O Windows não aceita caminhos dessa forma....
E assim por diante, adicionando um 'dirname' para cada nível abaixo na árvore de diretórios.Depois faça dessa forma:
include DOCUMENT_ROOT."/includes/arquivo.php";
Assim você evita variáveis globais através do uso de constantes.
Nesse caso, seria uma solução só para o Windows? Eu rodo aqui o site local (Windows) e o site é hospedado em servidor Linux...
E pelo que entendi, esse dirname daria o mesmo trabalho que os "..", já que não seria global e teria que analizar onde está sendo incluso... correto?
O erro apresentado lá pelo @Maghost é de resolução de caminho. O arquivo não existe no caminho especificado.
O caminho funciona para inclusões em geral (script, css, imagens...), só no caso do include que teria de especificar diferente? No meu caso teria que colocar:
"/xampp/htdocs/site" ao invés de apenas "/site"?
Valeu pelas dicas e opiniões, eu não tinha base direito disso, agora estou começando a entender. (a confusão por sinal kkk')
Usando dirname em conjunto com a constante mágica __FILE__ vai te retornar o caminho absoluto em relação ao arquivo onde o comando foi escrito.
Eu aconselho sempre fazer includes com caminhos absolutos, para não ter problema de resolução/confusão de escopo (como também mencionado pelo @Henrique).
Com caminhos absolutos, independe da plataforma (desde que o caminho esteja correto :P)
Para leitura: http://br.php.net/manual/en/ref.filesystem.php
Em especial: realpath, dirname e pathinfo.
em tempo: você também pode usar a constante mágica __DIR__ se estiver usando o PHP 5.3 ou superior. Neste caso __DIR__ == dirname(__FILE__)
@braços e fique com Deus!
Arquivo que ele tentou recuperar:
/site/includes/arquivo.php
Este é o caminho absoluto, mesma coisa que "C:\site\includes\arquivo.php", por conta da barra no inicio do nome do arquivo.
Aí é que tá, no Windows isso funciona só pra imagens, css, javascripts incluídos no HTML, pois esse comportamento é emulado pelo Apache.
O include do PHP interage direto com o filesystem e como o Windows é baseado em 'unidades', ao incluir um arquivo com caminho absoluto no Windows você precisa do C:\...
Da forma que mostrei, se estiver num ambiente Windows, ele irá retornar o caminho absoluto no formato Windows (C:\xamp\....). Se estiver num ambiente unix, irá retornar /home/usuario/public por exemplo.
Eu adoro essa portabilidade do PHP :love:.
E dizem que Java é "Write Once, Run Everywhere"... Balela!
@Henrique,
Cara, me desculpe, mas não entendi.
Ele está usando include, e não colocando imagens em um HTML. Imagens em HTML, bem como CSS e arquivos JavaScript não levam para a raiz do HD quando iniciados com forward-slash, e sim a raiz do dominio. Para que funcione com imagens, CSS, etc, poderia usar o protocolo file.aspx) para indicar o caminho no HD e ficar mais claro que se trata de um caminho no HD (o que na minha opinião seria uma tolice fazê-lo, mas enfim, cada um tem uma necessidade diferente do outro).
Como expliquei no meu post que você fez o quote, a barra no inicio de arquivos/diretórios no Windows com Apache, leva sim a raiz do HD (c:\ no meu caso), indicando caminho absoluto. Em meu ambiente de testes, estou usando este conjunto de softwares (windows 7 e apache 2.2).
Por isso, reafirmo: no Windows com Apache, não precisa colocar a letra da unidade para indicar o caminho absoluto para include/require.
Em meu ambiente de testes uso:
/www/cliente/includes
que é a mesma coisa que:
C:\www\cliente\includes
Mas, como falado anteriormente, a unica coisa que é quase imperceptível, ainda mais por ser ambiente de desenvolvimento, é que usar forward-slashes (/) no Windows, deixa a execução alguns milésimos de segundo mais lenta, por conta da resolução de pastas.
Para leitura: include, pathinfo, realpath e dirname.
@braços e fique com Deus!
Obrigado a todos que ajudaram, tirei minha dúvida sobre caminhos/diretórios.
Não sei como funciona aqui, mas se quiserem podem trancar o tópico. :thumbsup:
Sobre a questão "\" e "/", o PHP tem uma constante que lhe auxilia nisso:
DIRECTORY_SEPARATOR
O problema é o SO. O Windows não aceita caminhos dessa forma.
Tente fazer assim:
define('DOCUMENT_ROOT', dirname(__FILE__));
Caso o seu arquivo esteja na raiz do site. Caso esteja dentro de uma pasta que fica na raiz, faça:
define('DOCUMENT_ROOT', dirname(dirname(__FILE__)));
E assim por diante, adicionando um 'dirname' para cada nível abaixo na árvore de diretórios.Depois faça dessa forma:
include DOCUMENT_ROOT."/includes/arquivo.php";
Assim você evita variáveis globais através do uso de constantes.