относительный путь в require_once не работает

У меня есть следующая структура

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

Файл include.php имеет следующее

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

и на странице index.php я включил

require_once 'include/include.php';

Когда я открываю страницу index.php, я получаю следующее предупреждение и фатальную ошибку. Я не понимаю, что вызывает эту ошибку. Когда я дал абсолютный путь, он работает. Но я считаю, что абсолютный путь - не очень хорошая идея.

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

заранее спасибо


person user525146    schedule 20.03.2011    source источник
comment
Обычно я делаю Objective-C и пытаюсь освоить php-скрипты, и мне грустно видеть, что я уже потратил 2 часа на то, чтобы понять, как правильно включать файлы в PHP. С X-кодом все так просто.   -  person rohan-patel    schedule 18.06.2014
comment
С этой ошибкой часто сталкиваются, и для ее быстрого устранения выполните следующие действия: stackoverflow.com/a/36577021/2873507   -  person Vic Seedoubleyew    schedule 12.04.2016


Ответы (4)


Использовать

__DIR__

чтобы получить текущий путь к скрипту, и это должно решить вашу проблему.

So:

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

Это предотвратит случаи, когда вы можете запустить PHP-скрипт из другой папки, и поэтому относительные пути не будут работать.

Изменить: проблема с косой чертой исправлена

person Raisen    schedule 20.03.2011
comment
Осторожно! __DIR__ появился в PHP 5.3. Если вам нужно, чтобы этот скрипт работал в более ранних версиях PHP, вместо него следует использовать dirname(__FILE__). - person Charles; 21.03.2011
comment
Обратите внимание, что после __DIR__ следует вручную включить завершающую косую черту. Итак: require_once(__DIR__.'/../class/user.php'); Согласно документации косая черта в конце опускается, за исключением корневой каталог. - person Ariel Allon; 17.12.2012
comment
Спасибо за помощь, но я так и не понял, зачем нужен __DIR__. Документы PHP, кажется, говорят, что PHP по умолчанию будет искать текущий каталог скрипта. Кто-нибудь может пролить свет? - person David; 29.08.2013
comment
Спасибо! Работает как положено! - person ; 22.04.2014
comment
@David, я думаю, это необходимо, когда вы импортируете файл из двух мест одновременно. Например, у вас есть файл с require "../a.php". Если этот файл импортируется из другого файла (x) в dir1/dir2/x.php, включенный файл будет dir1/a.php, но если x находится в dir1/dir2/dir3/x.php, включенный файл будет dir1/dir2/a.php и т. д. Или я ошибаюсь? - person José Ramón; 20.11.2014
comment
Очень хороший ответ. Кто-нибудь знает, есть ли проблемы с эффективностью при использовании DIR? - person radhoo; 25.02.2015
comment
Теперь здесь есть контрольный список для устранения этой частой ошибки: stackoverflow.com/a/36577021/2873507 - person Vic Seedoubleyew; 12.04.2016

для php версии 5.2.17 __DIR__ не будет работать, будет работать только с php 5.3

А вот для старой версии php dirname(__FILE__) отлично

Например написать так

require_once dirname(__FILE__) . '/db_config.php';
person Mobile Tech.    schedule 03.10.2012

В моем случае это не работает, даже с __DIR__ или getcwd() он продолжает выбирать неправильный путь, я решил, определив константу в каждом файле, который мне нужен, с абсолютным базовым путем проекта:

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

У меня есть MAMP с php 5.4.10, и моя иерархия папок базовая:

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

....

person linuxatico    schedule 09.12.2013

Я только что столкнулся с этой же проблемой, когда все работало нормально, до тех пор, пока у меня не было включения внутри другого включения.

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

Решение 1. (нежелательное жесткое кодирование имени моей общедоступной HTML-папки, но оно работает):

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

Решение 2. (нежелательный комментарий выше о том, что DIR работает только с php 5.3, но работает):

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

Решение 3. (я не вижу никаких недостатков, и оно отлично работает на моем php 5.3):

require_once dirname(__FILE__). '/../script/pdocrud.php';
person hamish    schedule 06.08.2019