ścieżka względna w require_once nie działa

103

Mam następującą strukturę

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

include.php ma następujący plik

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';

i na stronie index.php, którą zamieściłem

require_once 'include/include.php';

Kiedy otwieram stronę index.php, otrzymuję następujące ostrzeżenie i błąd krytyczny. Nie rozumiem, co powoduje ten błąd. Kiedy podałem absolutną ścieżkę, to działa. Ale absolutna ścieżka nie jest dobrym pomysłem.

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

Z góry dziękuję

user525146
źródło
Zwykle robię Objective-C i próbuję opanować skrypty php i przykro mi, że zmarnowałem już 2 godziny na zastanawianie się, jak poprawnie dołączyć pliki do PHP. Z kodem X sprawy są takie proste.
rohan-patel
Często
napotyka

Odpowiedzi:

216

Posługiwać się

__DIR__

aby uzyskać aktualną ścieżkę do skryptu, co powinno rozwiązać problem.

Więc:

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

Zapobiegnie to przypadkom, w których można uruchomić skrypt PHP z innego folderu i dlatego ścieżki pokrewne nie będą działać.

Edycja: naprawiono problem z ukośnikiem

Raisen
źródło
42
Uważaj! __DIR__jest nowy w PHP 5.3. Jeśli potrzebujesz tego skryptu do działania we wcześniejszych wersjach PHP, powinieneś użyć dirname(__FILE__)zamiast tego.
Charles
27
Zauważ, że powinieneś ręcznie dołączyć końcowy ukośnik po __DIR__. Tak więc: zgodnie require_once(__DIR__.'/../class/user.php'); z dokumentacją końcowy ukośnik jest pomijany, z wyjątkiem katalogu głównego.
Ariel Allon
9
Dzięki za pomoc, ale nadal nie rozumiem, dlaczego __DIR__jest to konieczne. Dokumentacja PHP wydaje się mówić, że PHP domyślnie przeszuka katalog bieżącego skryptu. Czy ktoś może rzucić nieco światła?
David
1
@David Myślę, że jest to potrzebne, gdy importujesz plik z 2 miejsc w tym samym czasie. Na przykład masz plik z rozszerzeniem require "../a.php". Jeśli ten plik jest importowany z innego pliku (x) w dir1/dir2/x.phpdołączonym pliku będzie dir1/a.php, ale jeśli x jest w dir1/dir2/dir3/x.php, dołączony plik będzie dir1/dir2/a.phpitd. A może się mylę?
José Ramón
1
Jest teraz lista kontrolna rozwiązywania problemów dla tego częstego błędu tutaj: stackoverflow.com/a/36577021/2873507
Vic Seedoubleyew
17

dla php w wersji 5.2.17 __DIR__nie będzie działać, będzie działać tylko z php 5.3

Ale dla starszej wersji php dirname(__FILE__)doskonale

Na przykład napisz w ten sposób

require_once dirname(__FILE__) . '/db_config.php';
Mobile Tech.
źródło
1

W moim przypadku to nie działa, nawet z __DIR__lub getcwd()ciągle wybiera niewłaściwą ścieżkę, rozwiązałem, definiując koszt w każdym potrzebnym pliku z bezwzględną ścieżką bazową projektu:

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

Mam MAMP z php 5.4.10 i moja hierarchia folderów jest podstawowa:

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

....

linuxatico
źródło
0

Właśnie natknąłem się na ten sam problem, w którym wszystko działało dobrze, aż do momentu, gdy miałem zawarcie w innym dołączeniu.

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')

Rozwiązanie 1. (niepożądane zakodowanie nazwy mojego publicznego folderu html, ale działa):

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

Rozwiązanie 2. (niepożądany komentarz powyżej o DIR działającym tylko od php 5.3, ale działa):

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

Rozwiązanie 3. (nie widzę żadnych wad i działa idealnie w moim php 5.3):

require_once dirname(__FILE__). '/../script/pdocrud.php';
Hamish
źródło