Как включить файлы PHP, требующие абсолютного пути?

У меня есть структура каталогов, такая как:

script.php

вкл / include1.php
вкл / include2.php

Объекты / object1.php
Объекты / object2.php

мыло / soap.php

Теперь я использую эти объекты как в script.php /soap/soap.php , так и в /soap/soap.php , я могу их перемещать, но я хочу, чтобы структура каталогов была подобна этой причине. При запуске script.php путь include – inc/include.php а при выполнении /soap/soap.php это ../inc , работают абсолютные пути, /mnt/webdev/[project name]/inc/include1.php... Но это уродливое решение, если я когда-либо захочу переместить каталог в другое место.

Итак, есть ли способ использовать относительные пути или способ программно генерировать "/mnt/webdev/[project name]/" ?

Это должно работать

 $root = realpath($_SERVER["DOCUMENT_ROOT"]); include "$root/inc/include1.php"; 

Редактировать: добавлено imporvement by aussieviking

Вы можете использовать относительные пути. Попробуйте __FILE__ . Это постоянная PHP, которая всегда возвращает путь / имя файла скрипта, в котором он находится. Таким образом, в soap.php вы можете:

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

Полный путь и имя файла. Если используется внутри include, возвращается имя включенного файла. Начиная с PHP 4.0.2, __FILE__ всегда содержит абсолютный путь с символическими __FILE__ тогда как в более старых версиях он содержал относительный путь при некоторых обстоятельствах. (источник)

Другим решением было бы установить путь включения в ваш файл httpd.conf или .htaccess.

посмотрите http://au.php.net/reserved.variables

Я думаю, что переменная, которую вы ищете, это: $_SERVER["DOCUMENT_ROOT"]

Вы можете определить константу с указанием пути к корневому каталогу вашего проекта, а затем поместить его в начало пути.

Еще один способ справиться с этим, который вообще устраняет необходимость, заключается в использовании функции автозагрузки . Включение всего, что требует ваш сценарий «Just in Case», может помешать работе. Если вы включаете в себя все определения классов или интерфейсов и загружаете их только по мере необходимости, вы можете перегрузить __autoload() своим собственным кодом, чтобы найти соответствующий файл класса и загрузить его только при его вызове. Вот пример из руководства:

 function __autoload($class_name) { require_once $class_name . '.php'; } $obj = new MyClass1(); $obj2 = new MyClass2(); 

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

Другим вариантом, связанным с Kevin's, является использование __FILE__ , но вместо этого вместо него следует заменить имя файла php:

 <?php $docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__); require_once($docRoot . '/lib/include.php'); ?> 

Я использовал это некоторое время. Единственная проблема – иногда у вас нет $_SERVER['SCRIPT_NAME'] , но иногда есть и другая переменная.

Я нашел, что это работает очень хорошо!

 function findRoot() { return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1))); } 

Использование:

 <?php function findRoot() { return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1))); } include(findRoot() . 'Post.php'); $posts = getPosts(findRoot() . 'posts_content'); include(findRoot() . 'includes/head.php'); for ($i=(sizeof($posts)-1); 0 <= $i; $i--) { $posts[$i]->displayArticle(); } include(findRoot() . 'includes/footer.php'); ?> 
 require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php"); 

Я использую эту строку кода. Он возвращается к «вершине» дерева сайта, затем переходит к желаемому файлу.

Например, допустим, у меня есть это дерево файлов:

domain.com/aaa/index.php
domain.com/bbb/ccc/ddd/index.php
domain.com/_resources/functions.php

Я могу включить файл functions.php из любого места, где бы я ни находился, просто путем копирования вставки

 require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/_resources/functions.php"); 

Если вам нужно использовать этот код много раз, вы можете создать функцию, которая возвращает str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1)) . Затем просто вставьте эту функцию в первый файл, который вы включили. У меня есть файл initialize.php, который я включаю в самый верх каждой страницы php и который содержит эту функцию. В следующий раз, когда я должен включить файлы, я на самом деле просто использую функцию (named path_back ):

 require(path_back()."/_resources/another_php_file.php"); 

Я думаю, что лучший способ – включить ваши включения в ваш путь PHP include. Существуют различные способы сделать это в зависимости от вашей настройки.

Тогда вы можете просто обратиться к

 require_once 'inc1.php'; 

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

Это позволяет иметь ваши файлы include вне корня веб-сервера, что является наилучшей практикой.

например

 site directory html (web root) your web-accessible files includes your include files 

Кроме того, проверьте __autoload для ленивой загрузки файлов классов

http://www.google.com/search?q=setting+php+include+path

http://www.google.com/search?q=__autoload

@Flubba, это позволяет мне иметь папки внутри моего каталога include? Плоские включенные каталоги дают мне кошмары. так как весь каталог объектов должен находиться в каталоге inc.

О да, абсолютно. Так, например, мы используем один слой подпапок, как правило:

 require_once('library/string.class.php') 

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

Так, например, если вы делаете MVC, вы поместите путь к вашему приложению directoy в путь include и затем укажите ссылку на вещи в форме

 'model/user.class' 'controllers/front.php' 

или что-то еще.

Но, вообще говоря, это просто позволяет вам работать с очень короткими путями на вашем PHP, который будет работать в любом месте, и его гораздо легче читать, чем весь этот корень malpathy.

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

Более короткий путь

 include($_SERVER['DOCUMENT_ROOT']."/inc/include1.php"); 

'DOCUMENT_ROOT': корневой каталог документа, под которым выполняется текущий скрипт, как определено в файле конфигурации сервера.