Включают ли PHP пути относительно файла или вызывающего кода?


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

Author: Yarin, 2011-09-11

6 answers

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

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

Нет.

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

include(dirname(__FILE__)."/C.PHP");
 115
Author: Pekka 웃, 2017-05-15 20:26:13

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

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

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

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

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

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

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

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

Источники:

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

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

 20
Author: Yarin, 2017-05-23 12:18:19
  1. Если путь включения не начинается с ./ или ../, например:

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

 13
Author: Johnny Wong, 2015-03-26 02:50:47

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

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

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

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

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

 11
Author: , 2015-02-07 23:01:46

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

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

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

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

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

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

 4
Author: Denis Howe, 2012-12-12 19:19:44
dir
-> a.php
-> c.php

- dir2 
-> b.php

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

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

 -1
Author: Olli, 2011-09-11 14:23:21