Вложенные директивы `include()` — Как включить файл (который включает другой) из более чем одного каталога?

#path #include #php #include-path

#путь #включить #php #включить-path

Вопрос:

У меня есть эти три файла для работы:

document_root/include/config.php
document_root/include/database.php
document_root/index.php

И соответствующая часть содержимого файла выглядит следующим образом:

config.php

 // ...
$MyVar = 100;
// ...
  

database.php

 // ...
require('config.php');
// Aiming to use the definitions in "config.php" here
// ...
  

index.php

 // ...
require('include/database.php');
// Using the code in "database.php" here
// ...
  

Проблема в том, что config.php каким-то образом не включен, и при этом сообщение об ошибке не выдается (в режиме E_ALL). Я не могу получить доступ к определениям в config.php файле из database.php file во время выполнения кода в index.php .

В моем PHP.ini файле include_path установлено значение C:...document_rootinclude directory.
Версия PHP — 5.3.0.

Я заметил, что, если я изменю require() директиву в database.php как
require('include/config.php'); код выполняется без каких-либо сбоев, и все просто отлично. Но это решение невозможно на практике, потому что я планирую включить config.php файл из нескольких расположений.

В чем причина этой проблемы?
Как я могу это исправить?

Любая помощь будет оценена.

Ответ №1:

Причина этой проблемы заключается в том, что include разрешаются относительные имена файлов на основе рабочего каталога, а не на основе каталога, в котором находится файл, который выполняет include .

Рабочий каталог — это каталог PHP-файла, который запускается веб-сервером (в вашем случае index.php , я полагаю). Если этот файл включает в себя какой-либо другой файл, рабочий каталог не изменяется. Его можно изменить вручную с помощью chdir , но вы не должны делать это исключительно ради include .

Одним из возможных решений является использование

 include dirname(__FILE__) . DIRECTORY_SEPARATOR . '[RELATIVE_PATH]';
  

где [RELATIVE_PATH] — относительный путь от файла, который включает, к файлу, который включен.

В PHP 5.3 __DIR__ может использоваться вместо dirname(__FILE__) .

Комментарии:

1. Ваш ответ хорош и работает, большое спасибо. Но я хочу узнать причину, по которой я должен указывать путь при включении файла, даже если его путь уже указан в PHP.ini директиве include_path ? Почему этот общий параметр здесь не применяется?

2. На самом деле я сам немного запутался. В документации для include говорится «… include() , наконец, проверит собственный каталог вызывающего скрипта …», что означает, что у вас не должно было возникнуть проблемы в первую очередь. Я уверен, что цитируемой части там не было, когда я проверял в последний раз.