caminho relativo em require_once não funciona

103

Eu tenho a seguinte estrutura

otsg
 > class
   > authentication.php
   > database.php
   > user.php
 > include
   > config.inc.php
   > encryption.php
   > include.php
   > session.php
 > index.php
 > registration.php

O arquivo include.php tem o seguinte

ini_set('display_errors', 1);
error_reporting(E_ALL);

ini_set('include_path',ini_get('include_path').':/Applications/MAMP/htdocs/otsg/:');
require_once 'config.inc.php';
require_once '../class/database.php';
require_once '../class/user.php';
require_once 'encryption.php';
require_once 'session.php';
require_once '../class/authentication.php';

e na página index.php eu incluí

require_once 'include/include.php';

Quando abro a página index.php, recebo o seguinte aviso e erro fatal. Não entendo o que causa esse erro. Quando dei o caminho absoluto, funciona. Mas o caminho absoluto não é uma boa ideia, eu acredito.

Warning: require_once(../class/database.php) [function.require-once]: failed to open stream: No such file or directory in /Applications/MAMP/htdocs/otsg/include/include.php on line 9

Fatal error: require_once() [function.require]: Failed opening required '../class/database.php' (include_path='.:/Applications/MAMP/bin/php5.3/lib/php:/Applications/MAMP/htdocs/otsg/include/:') in /Applications/MAMP/htdocs/otsg/include/include.php on line 9

desde já, obrigado

user525146
fonte
Normalmente estou fazendo Objective-C e tentando colocar minhas mãos em scripts php e triste ver que já perdi 2 horas descobrindo como incluir arquivos corretamente em PHP. As coisas são tão fáceis com o código-X.
rohan-patel de
Muitas vezes encontramos esse erro e, para solucioná-lo rapidamente, siga estas etapas: stackoverflow.com/a/36577021/2873507
Vic Seedoubleyew

Respostas:

216

Usar

__DIR__

para obter o caminho atual do script e isso deve resolver seu problema.

Assim:

require_once(__DIR__.'/../class/user.php');

Isso evitará casos em que você possa executar um script PHP de uma pasta diferente e, portanto, os caminhos relativos não funcionarão.

Editar: problema de barra corrigido

Raisen
fonte
42
Cuidado! __DIR__é novo no PHP 5.3. Se você precisa que este script seja executado em versões anteriores do PHP, você deve usá-lo dirname(__FILE__).
Charles de
27
Observe que você deve incluir manualmente a barra final depois __DIR__. Portanto: De require_once(__DIR__.'/../class/user.php'); acordo com a documentação , a barra final é omitida, exceto para o diretório raiz.
Ariel Allon
9
Obrigado pela ajuda, mas ainda não entendo porque __DIR__é necessário. Os documentos do PHP parecem dizer que o PHP pesquisará o diretório do script atual por padrão. Alguém pode lançar alguma luz?
David
1
@David Acho que isso é necessário quando você importa um arquivo de 2 lugares ao mesmo tempo. Por exemplo, você tem um arquivo com require "../a.php". Se este arquivo for importado de outro arquivo (x), dir1/dir2/x.phpo arquivo incluído será dir1/a.php, mas se x estiver dir1/dir2/dir3/x.php, o arquivo incluído será dir1/dir2/a.php, etc. Ou estou errado?
José Ramón de
1
Agora há uma lista de verificação de solução de problemas para este erro frequente aqui: stackoverflow.com/a/36577021/2873507
Vic Seedoubleyew
17

para php versão 5.2.17 __DIR__não funcionará, só funcionará com php 5.3

Mas para uma versão mais antiga do php dirname(__FILE__)perfeitamente

Por exemplo, escreva assim

require_once dirname(__FILE__) . '/db_config.php';
Mobile Tech.
fonte
1

No meu caso ele não funciona, mesmo com __DIR__ou getcwd()mantém escolher o caminho errado, eu resolvido, definindo um costant em cada arquivo que eu preciso com o caminho de base absoluta do projeto:

if(!defined('THISBASEPATH')){ define('THISBASEPATH', '/mypath/'); }
require_once THISBASEPATH.'cache/crud.php';
/*every other require_once you need*/

Eu tenho MAMP com php 5.4.10 e minha hierarquia de pastas é basilar:

q.php 
w.php 
e.php 
r.php 
cache/a.php 
cache/b.php 
setting/a.php 
setting/b.php

....

linuxatico
fonte
0

Acabei de me deparar com o mesmo problema, onde tudo funcionava bem, até o ponto em que tinha um includes dentro de outro includes.

require_once '../script/pdocrud.php';  //This worked fine up until I had an includes within another includes, then I got this error:
Fatal error: require_once() [function.require]: Failed opening required '../script/pdocrud.php' (include_path='.:/opt/php52/lib/php')

Solução 1. (codificação indesejada do nome da minha pasta html pública, mas funciona):

require_once $_SERVER["DOCUMENT_ROOT"] . '/orders.simplystyles.com/script/pdocrud.php';

Solução 2. (comentário indesejado acima sobre o DIR só funcionar desde o php 5.3, mas funciona):

require_once __DIR__. '/../script/pdocrud.php';

Solução 3. (Não consigo ver nenhuma desvantagem e funciona perfeitamente no meu php 5.3):

require_once dirname(__FILE__). '/../script/pdocrud.php';
hamish
fonte