Как включить файлы 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]/"?

93 php
7.08.2008 03:46:47
11 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

Редактировать: добавлено улучшение от aussieviking

149
23.05.2017 11:47:20
Будьте осторожны, это сработает только в том случае, если вы запустите скрипт через веб-сервер, который заполняетсяDOCUMENT_ROOT
Phil 22.12.2013 23:03:37
просто вопрос, почему realpath () для $ _SERVER ["DOCUMENT_ROOT"]? Это не должно выводить всегда канонический путь?
João Pimentel Ferreira 15.11.2015 00:30:30

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

5
7.08.2008 04:04:55

взгляните на http://au.php.net/reserved.variables

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

6
12.07.2011 23:50:49

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

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

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

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

44
9.09.2017 01:01:54
Я думаю, что вы должны добавить /в начале выражения в кавычках, чтобы отделить ..от имени файла .
Dunaril 8.08.2011 13:07:45
Обратите внимание, что начиная с PHP 5.3.0 вы можете использовать магическую константу, __DIR__а не использовать dirname(__FILE__). (PHP документы)
Erwin Wessels 15.05.2012 09:05:52
include dirname(__FILE__).'/../inc/include.php';Не забывайте "/" перед относительным путем.
Steven Leimberg 27.06.2014 20:53:10

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

1
7.08.2008 19:23:14

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

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

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

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

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

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

или что угодно.

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

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

0
8.08.2008 23:17:12

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

<?php

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

?>

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

2
27.11.2013 18:23:02

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

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

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

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

6
18.09.2008 14:28:50

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

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

?>
2
4.03.2017 10:24:34
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");
1
13.04.2015 14:37:07

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

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

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

0
9.05.2018 10:10:21