Как заставить эти PHP-включения работать?

#php #path #include

#php #путь #включить

Вопрос:

У меня есть следующая структура файла:

 /
 --- inc/
|     --- lib1.php
 --- inc2/
|     --- lib2.php
|     --- view2.php
 --- view1.php
  

Оба view1.php и view2.php включить lib2.php . Lib2.php включает lib1.php . Графически:

 View1.php ---
              ---> Lib2.php ---> Lib1.php
View2.php ---/
  

Однако я не могу заставить это работать, потому что пути поиска шаткие. Если я попытаюсь включить «../lib1.php «тогда только view2.php работает. Если я попытаюсь включить «inc/lib1.php «, тогда только view1.php работает. Другое представление всегда жалуется на то, что файл не найден.

Каким должен быть правильный способ справиться с этим?

Ответ №1:

Если вы используете php > = 5.3, вы можете использовать __DIR__ для построения пути. Если нет, используйте dirname(__FILE__) So в lib2.php просто поместите это:

 require_once(__DIR__ . '../inc/lib1.php');
  

Комментарии:

1. Если вы используете только ‘../’, это относится к рабочему каталогу, в котором выполняется скрипт, поэтому использование __FILE__ или __DIR__ — это простой способ достичь того, что вы на самом деле ищете. Документы здесь: php.net/manual/en/language.constants.predefined.php

2. Рад, что вам это нравится! И рад, что они представили __DIR__ , другое решение выглядело немного странно.

3. Всем нравится __DIR__ , похоже, это было самое время 🙂

4. @hakre «Итак, в lib2.php просто поместите это […]» — проблема с этим. Вы инструктируете читателя добавить то, что составляет self-include, что определенно приведет их в замешательство. Возможно, вы захотите отредактировать для наглядности.

5. @Obsidian_ : Я думаю, вы обращались ко мне, рад, что вы заметили эту проблему!

Ответ №2:

В ваших пользовательских файлах определите константу следующим образом (здесь предполагается PHP 5.3):

 <?php
define('ROOT_INCLUDE_PATH', __DIR__ . '/');
  

Теперь в любой файл вашего проекта, который включен вашими пользовательскими файлами, вы просто используете простое включение.

Следующий фрагмент будет view1.php:

 <?php
define('ROOT_INCLUDE_PATH', __DIR__ . '/');
// ...
include ROOT_INCLUDE_PATH . 'inc/lib1.php';
include ROOT_INCLUDE_PATH . 'inc2/lib2.php';
  

И это было бы view2.php (обратите внимание, что здесь мы используем dirname() для создания корневого пути к каталогу):

 <?php
define('ROOT_INCLUDE_PATH', dirname(__DIR__) . '/');
// ...
include ROOT_INCLUDE_PATH . 'inc/lib1.php';
include ROOT_INCLUDE_PATH . 'inc2/lib2.php';
  

Это означает, что ваши включения могут включать другие включения вообще без каких-либо изменений; пока вы соответствующим образом определяете корневой путь включения в своих пользовательских файлах, все хорошо.

Комментарии:

1. 1 для этого проекта разработан корневой путь, но что вы подразумеваете под «файлами, обращенными к пользователю»?

2. @greg0ire — все, с чем пользователь взаимодействует напрямую; это полярная противоположность включаемому файлу, файлу библиотеки, к которому пользователь никогда не обращается (но включается во время выполнения). по сути, это страница, на которую пользователь отправляет запрос.

3. Я идиот. Это должно быть dirname (), а не basename() . /me редактирует

Ответ №3:

Поскольку полагаться на относительный путь не сработает, я думаю, что возможным решением является использование абсолютного пути. Объявите $system_path = "/" как глобальную переменную, чтобы вы всегда могли включить на основе системного пути.

Комментарии:

1. Даже если это работает, это предотвращает переносимость кода, например, когда вы помещаете его в другую систему.

2. На самом деле лучше сделать это как константу, а не глобальную переменную.