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

У меня есть следующая структура каталогов;

script.php

inc / include1.php
inc / include2.php

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

мыло / soap.php

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

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

Ответов (11)

Решение

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

$root = realpath($_SERVER["DOCUMENT_ROOT"]);

include "$root/inc/include1.php";

Изменить: добавлено улучшение от aussieviking

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

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');

?>

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

define("APPLICATION_PATH", realpath(dirname(__FILE__) . '/../app'));
or 
define("APPLICATION_PATH", realpath(DIR(__FILE__) . '/../app'));

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

БЫВШИЙ:

include(APPLICATION_PATH ."/config/config.ini";

Надеюсь, это поможет ;-)

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

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

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

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

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

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

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

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

Тогда вы можете просто сослаться на

require_once 'inc1.php';

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

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

например

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

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

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

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

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

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

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

<?php

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

?>

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

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

function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

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

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

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