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


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

6 94

6 ответов:

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

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

нет.

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

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

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

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)

  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 '.'
    

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

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

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

принятый ответ Пекки является неполным и, в общем контексте, вводящим в заблуждение. Если файл предоставлен в виде относительного пути, то вызываемая языковая конструкция 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, включать будет наконец, проверьте собственный вызывающий скрипт каталог и текущий рабочий каталог перед сбоем.

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

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

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

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

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

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

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

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

dir
-> a.php
-> c.php

- dir2 
-> b.php

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

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