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

У меня есть структура каталогов, как показано ниже;

script.php

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

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

мыло /soap.php

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Другим решением было бы установить include path в вашем файле httpd.conf или .htaccess.

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

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

<?php

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

?>

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

Ответ 7

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

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

?>

Ответ 8

Я думаю, что лучший способ - включить ваши включенные в ваш путь 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

Ответ 9

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

Ответ 10

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

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

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

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

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

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

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

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

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

Ответ 11

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

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

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

Ответ 12

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

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

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

EX:

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

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