Являются ли PHP включением путей относительно файла или кода вызова?

У меня возникли проблемы с пониманием набора правил относительно относительных включений PHP, включая пути. Если я запускаю файл A.PHP- и файл A.PHP включает в себя файл B.PHP, который включает файл C.PHP, должен ли относительный путь к C.PHP относиться к местоположению B.PHP или к местоположению A .PHP? То есть, имеет ли значение, из какого файла вызывается вызов, или только то, что является текущим рабочим каталогом, и что определяет текущий рабочий каталог?

Это относительно основного сценария, в данном случае A.php. Помните, что include() просто вставляет код в текущий скрипт.

То есть, имеет ли значение, из какого файла вызывается вызов include

Нет.

Если вы хотите, чтобы это имело значение, и укажите include относительно B.php, используйте константу __FILE__ (или __DIR__ с PHP 5.2 IIRC), которая всегда будет указывать на текущий текущий файл, в котором находится строка кода.

 include(dirname(__FILE__)."/C.PHP"); 

@Pekka меня там, но просто хочу поделиться тем, что узнал:

getcwd() возвращает каталог, в котором находится исполняемый файл.

dirname(__FILE__) возвращает каталог файла, содержащего dirname(__FILE__) исполняемый код.

Используя эти две функции, вы всегда можете создать путь включения относительно того, что вам нужно.

например, если b.php и c.php совместно используют каталог, b.php может включать c.php, например:

 include(dirname(__FILE__).'/c.php'); 

независимо от того, откуда был вызван b.php.

Фактически, это предпочтительный способ установления относительных путей, поскольку дополнительный код освобождает PHP от необходимости перебирать путь include_path в попытке найти целевой файл.

Источники:

Разница между getcwd () и dirname (__ FILE__)? Что я должен использовать?

Почему вы должны использовать dirname ( FILE )

Принятый ответ Пекки является неполным и, в общем контексте, вводит в заблуждение. Если файл предоставлен как относительный путь, конструктор вызываемого языка будет искать его следующим образом.

Во-первых, он будет проходить через пути переменной окружения include_path , которые могут быть установлены с помощью ini_set . Если это не удается, оно будет искать в собственном каталоге dirname(__FILE__) вызывающего скрипта dirname(__FILE__) с php> = 5.3.) Если это также не удастся, только тогда он будет искать в рабочем каталоге! Просто получается, что по умолчанию начинается переменная среды include_path . , который является текущим рабочим каталогом. Это единственная причина, по которой он сначала ищет в текущем рабочем каталоге. См. http://php.net/manual/en/function.include.php .

Файлы включаются в зависимости от заданного пути к файлу или, если ни один не указан, указан путь include_path. Если файл не найден в include_path, включите, наконец, проверите собственный каталог вызывающего сценария и текущий рабочий каталог перед сбоем.

Итак, правильный ответ на первую часть вопроса состоит в том, что имеет значение, где находится включенный вызывающий скрипт. Ответ на последнюю часть вопроса заключается в том, что исходный рабочий каталог в контексте веб-сервера представляет собой каталог вызываемого скрипта, скрипт, который включает в себя все остальные, когда обрабатывается PHP. В контексте командной строки исходный рабочий каталог – это то, что происходит при вызове php в приглашении, а не в каталоге, в котором находится вызываемый скрипт. Однако текущий рабочий каталог можно изменить во время выполнения с помощью функции PHP chdir . См. http://php.net/manual/en/function.chdir.php .

Этот параграф добавляется для комментариев к другим ответам. Некоторые упомянули, что использование include_path менее надежное, и поэтому предпочтительнее использовать полные пути, такие как ./path или ./path __DIR__ . /path __DIR__ . /path . Некоторые дошли до того, что полагались на рабочий каталог . сама по себе небезопасна, потому что ее можно изменить. Однако несколько раз вам нужно полагаться на значения среды. Например, вам может потребоваться установить include_path пустым, так что каталог вызывающего сценария будет первым местом, которое он будет искать, даже до текущего рабочего каталога. Код может быть уже написан и регулярно обновляться из внешних источников, и вы не хотите повторно вставлять префикс __DIR__ каждый раз, когда код обновляется.

  1. Если включить путь не начинается с ./ или ../ , например:

     include 'C.php'; // precedence: include_path (which include '.' at first), // then path of current `.php` file (ie `B.php`), then `.`. 
  2. Если включить путь начинается с ./ или ../ , например:

     include './C.php'; // relative to '.' include '../C.php'; // also relative to '.' 

. или .. выше относится к getcwd() , который по умолчанию соответствует пути файла .php записи. (т.е. A.php ).

Протестировано на PHP 5.4.3 (Дата сборки: 8 мая 2012 г. 00:47:34).

(Также обратите внимание, что chdir() может изменять вывод getcwd() .)

Короткий ответ: это относительно сценария включения.

TFM объясняет это правильно:

Если файл не найден в include_path, include будет проверять каталог вызывающего скрипта и текущий рабочий каталог

Итак, если /app/main.php говорит include("./inc.php") , который найдет /app/inc.php .

Параметр ./ не является строго необходимым, но удаляет любую зависимость от include_path.

Я бы не стал полагаться на поиск включенных файлов в текущем рабочем каталоге, если кто-то изменит его с помощью chdir() .

 dir -> a.php -> c.php - dir2 -> b.php 

Чтобы включить a в b вам необходимо include("../a.php");

Чтобы включить b в c вам нужно include("dir2/b.php");