У меня возникли проблемы с пониманием набора правил относительно относительных включений 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");