У меня возникли проблемы с пониманием набора правил относительно относительных включений 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__ каждый раз, когда код обновляется.
Если включить путь не начинается с ./ или ../ , например:
include 'C.php'; // precedence: include_path (which include '.' at first), // then path of current `.php` file (ie `B.php`), then `.`.
Если включить путь начинается с ./ или ../ , например:
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");