2010-05-18 1 views
3

Во многих местах в моем коде, я такие вещи, как:PHP вложенный включает поведение

file1.php: 
<?php 
include('../file2.php'); 

file2.php: 
<?php 
include('anotherdirectory/file3.php'); 

В зависимости от сервера или настроек я пытаюсь это дальше, он либо устанавливает относительные пути от «includer» или «в том числе». Это действительно сбивает с толку. Итак, файл1 может попытаться включить «../anotherdirectory/file3.php» или попробовать «anotherdirectory/file3.php».

Какие настройки диктуют это поведение? Я хочу иметь контроль над этим ...

ответ

10

В тех случаях, когда мне нужно использовать относительные пути я использую следующий синтаксис:

include (realpath(dirname(__FILE__)."/another_folder/myfile.php")); 
+0

Фантастический! Это отягощает меня в течение многих лет - спасибо. –

+0

Отсутствует правая сторона? –

+0

@ BobStein-VisiBone: хорошее место, исправлено ... спасибо. – a1ex07

8

Я бы рекомендовал использовать абсолютные пути. Хороший способ сделать это в то же время является портативным, чтобы сделать заявление, как это в вашей public_html/index.php:

define('ROOT', dirname(__FILE__)); 

Затем вы можете написать включает в себя, как это, которое очень легко:

include(ROOT.'/file.php'); 

В противном случае PHP проверяет, находится ли файл в include path, как определено вашим php.ini. Если его нет, он пытается относительный путь к текущему скрипту. Это непредсказуемо и неподъемно, так как вы можете включать в себя файлы из разных относительных местоположений.

Редактировать: Если вы постоянно включаете в себя много файлов классов, вы можете посмотреть в autoloading. Все упрощается, если вы программируете в объектно-ориентированном стиле. Я лично никогда не писал слово «включить» в свой код в течение очень долгого времени.

Редактировать 2: Вы можете использовать php.ini directiveauto_prepend_file, чтобы автоматически включать однострочный файл с определением ROOT в каждый из ваших сценариев.

+0

Просьба пояснить причину понижения, я буду открыт для изучения лучших методов. –

+0

Но тогда мне пришлось бы включить файл, который будет иметь этот «define()». Поэтому я вернусь к той же проблеме. –

+1

Хорошая точка. Оптимально, ваш index.php будет маршрутизировать все запросы к соответствующему скрипту с помощью mod_rewrite, но это другой вопрос сам по себе. Почти все приложения MVC (Model-View-Controller) делают это. –

0

С get_include_path() вы можете увидеть, что конфигурация сервера для этого есть. В большинстве случаев это выглядит следующим образом:

.:/usr/lib/php 

Это означает, что первое место PHP ищет включаемый файл является каталогом скрипта, который включает в себя другой. Если его нет, php ищет в/usr/php/lib. Если вы добавите больше путей, php также будет искать там соответствующий файл.

Если вы включаете файл, который включает в себя другой, путь «root» - это путь к файлу, который сначала включал в себя другой.

1

Как кто-то на кривой обучения php, я нашел, что лучший способ ссылки включать пути - это абсолютное местоположение, а не относительное, с помощью встроенного супер-локуса $ _SERVER. В моих собственных файлов я использую это с успехом:

include $_SERVER [ 'DOCUMENT_ROOT' ] . '/path_from_root/file_name.php'; 

Таким образом, это не имеет значения, где включен файл находится относительно моего вызывающего файла, и я не придется беспокоиться о вручную вводить в моем полный путь к серверу. (Возможно, очевидно ..) Это будет работать независимо от того, как вложенной вызов include, и если/когда я перемещаю вызывающий файл в другой каталог, например.

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

На соответствующую записку ..

$_SERVER [ 'PHP_SELF' ] 

возвращает путь (относительно корня) текущего файла. Я также использую это совсем немного.

$ _SERVER имеет другую полезную информацию вы можете проверить здесь:

http://php.net/manual/en/reserved.variables.server.php

К сожалению, если это старая нить, я здесь новый.

EDIT: вы можете сохранить этот «DOCUMENT_ROOT» в переменной, которая будет использоваться позже, но из недавнего опыта я бы рекомендовал против нее, потому что тогда вам нужно беспокоиться о области переменных. Строка включения, как написано, будет работать каждый раз независимо от текущей области.