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

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

Ответ 1

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

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

Нет.

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

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

Ответ 2

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

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

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)

Ответ 3

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

    include 'C.php'; // precedence: include_path (which include '.' at first),
                     // then path of current `.php` file (i.e. `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().)

Ответ 4

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

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

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

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

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

Ответ 5

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

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

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

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

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

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

Ответ 6

dir
-> a.php
-> c.php

- dir2 
-> b.php

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

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