Як включити PHP-файли, які вимагають абсолютного шляху?


95

У мене така структура каталогів, як наведена нижче;

script.php

inc / include1.php
inc / include2.php

objects / object1.php
objects / object2.php

мило / мило.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]/"?

Відповіді:


149

Це має спрацювати

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

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

Редагувати: додано імплементацію австралійським транспортом


2
Будьте обережні, це спрацює лише коли ви виконуєте сценарій через веб-сервер, який заповнюєтьсяDOCUMENT_ROOT
Філ

просто запитання, чому realpath () для $ _SERVER ["DOCUMENT_ROOT"]? Це не завжди виводить канонічний шлях?
Жоао Піментель Феррейра,

44

Ви можете використовувати відносні шляхи. Спробуйте __FILE__. Це константа PHP, яка завжди повертає шлях / ім'я файлу сценарію, в якому вона знаходиться. Отже, в soap.php, ви можете зробити:

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

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

Іншим рішенням було б встановити шлях включення у файл httpd.conf або файл .htaccess.


8
Я думаю, вам слід додати a /на початку цитованого виразу, щоб відокремити ім'я ..від FILE .
Дунаріл

9
Зверніть увагу, що з PHP 5.3.0 ви можете використовувати магічну константу, __DIR__а не використовувати dirname(__FILE__). (Документи PHP)
Ервін Вессель,

3
include dirname(__FILE__).'/../inc/include.php';Не забудьте "/" перед відносним шляхом.
Стівен Леймберг,

6

Інший спосіб вирішити це питання, який усуває будь-яку потребу в включенні, - це використовувати автозавантаження . Включення всього, що потрібно для вашого сценарію, "Про всяк випадок" може погіршити продуктивність. Якщо ваші включення - це всі визначення класу або інтерфейсу, і ви хочете завантажувати їх лише за потреби, ви можете перевантажити __autoload()функцію власним кодом, щоб знайти відповідний файл класу та завантажити його лише тоді, коли він викликаний. Ось приклад з посібника:

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

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

Поки ви відповідно встановлюєте свої змінні include_path, вам більше ніколи не потрібно буде включати файл класу.



5

Ви можете визначити константу із шляхом до кореневого каталогу вашого проекту, а потім поставити її на початку шляху.


2

Інший варіант, пов'язаний з Кевіном, - це використання __FILE__, але замість цього замініть ім'я файлу php всередині нього:

<?php

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

?>

Я використовую це вже деякий час. Єдина проблема - іноді у вас немає $_SERVER['SCRIPT_NAME'], але іноді є інша змінна, схожа.


2

Я знайшов, що це дуже добре працює!

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

?>

1

Я думаю, що найкращим способом є розміщення ваших включень у вашому шляху включення 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
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");

0

@Flubba, чи дозволяє це мені мати папки всередині мого каталогу включення? квартира включає каталоги дають мені кошмари. оскільки весь каталог об’єктів повинен знаходитись у каталозі inc.

О так, абсолютно. Так, наприклад, ми використовуємо один шар підпапок, як правило:

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

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

Так, наприклад, якщо ви робите MVC, ви вкладете шлях до директора додатка у шлях включення, а потім вкажете посилання на речі у формі

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

чи що завгодно.

Але загалом кажучи, це просто дозволяє вам працювати з дуже короткими шляхами у вашому PHP, які працюватимуть з будь-якого місця, і це набагато легше для читання, ніж весь той кореневий malarkey документа realpath.

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


0

Якщо ви збираєтеся включити певний шлях до більшості файлів у своїй програмі, створіть глобальну змінну для вашої кореневої папки.

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

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

ЕКС:

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

Сподіваюся, це допоможе ;-)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.