Як мені включити файл із 2 каталогами назад?


94

Як ви включаєте файл із понад 2 каталогами назад. Я знаю, що ви можете використовувати ../index.phpдля включення файлу, який має 2 каталоги назад, але як це зробити для 3 каталогів назад? Це має сенс? Я спробував, .../index.phpале це не працює.

У мене є файл, /game/forum/files/index.phpі він використовує PHP include, щоб включити файл. Яка знаходиться в /includes/boot.inc.php; /є кореневим каталогом.


chdir ('' ../ '');
maheshmnj

Відповіді:


152

..вибирає батьківський каталог із поточного. Звичайно, це можна прикувати:

../../index.php

Це було б два каталоги.


1
@Brian Ну, це дурниця, ти порівнюєш яблука та апельсини. Ви маєте рацію, що тут defineбуде використано a , але (1) це навіть не було віддаленим питанням. І (2) ви все одно використовували б відносний шлях у своєму define, якщо ви насправді не жорстко кодуєте весь абсолютний шлях до сервера, і я б утримався від цього, оскільки він має лише недоліки. Або (третя альтернатива) ви можете використовувати маніпуляцію рядками для вилучення батьківського каталогу із (розширеного) поточного шляху, але знову ж таки це не має жодних переваг щодо використання відносних шляхів.
Конрад Рудольф

На жаль, це може працювати на одному пристрої, а не на іншому, /../може працювати або ../може працювати, або ж не може працювати на трьох різних комп'ютерах із точно однаковим налаштуванням середовища
Дуглас Гаскелл,

@DouglasGaskell Ні, це неправильно. Позначення відносного шляху, включаючи ../та ../../(примітка: без провісної риски!), Працює на всіх сучасних операційних системах. Він використовується для не працювати на Windows , і ( довго назад) Macintosh , але тепер він працює всюди, і має , принаймні , за останні десять років. Якщо це десь не працює, то причина в тому, що структура файлів інша, і / або ви перебуваєте в іншому робочому каталозі. Але це не пов’язано з цим кодом.
Конрад Рудольф,

Конрад, я згадую про це, оскільки я щойно розібрався з цією проблемою 10 хвилин тому після спільного використання сховища з колегою за допомогою знімка віртуальної машини. Чомусь усі шляхи повинні були проходити /../замість того, щоб у ../його оточенні.
Дуглас Гаскелл,

@DouglasGaskell І я можу з упевненістю сказати вам, що помилка не пов’язана. Насправді шлях /../просто не має сенсу в будь-якій системі (це еквівалентно /або помилка). Ви впевнені, що не вставляєте щось перед цим?
Конрад Рудольф,

51

Щоб включити файл назад в один каталог, використовуйте '../file'. Для двох каталогів назад використовуйте '../../file'. І так далі.

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

require_once($_SERVER['DOCUMENT_ROOT'] . 'directory/directory/file');

DOCUMENT_ROOT - це змінна сервера, яка представляє базовий каталог, в якому знаходиться ваш код.


2
Привіт, Ден, швидке запитання: Ви говорите: " Реально ви не повинні виконувати включення щодо поточного каталогу ". А як щодо всіх відносних шляхів, які розміщені в більшості документів HTML? Якби я перемістив свій файл, чи не зламалися б і вони? Чи існує стандарт, коли використовувати відносні та абсолютні посилання? Заздалегідь спасибі!
Govind Rai

2
я думаю, що в ньому відсутня одна коса риса, це має бути: require_once ($ _ SERVER ['DOCUMENT_ROOT']. '/ directory / directory / file');
user889030

@ user889030, наскільки мені відомо, ця коса риса не потрібна, принаймні в більшості випадків
BotMaster3000


27
. = current directory
.. = parent directory

Так ../ви отримуєте один каталог назад, а не два .

Ланцюжок ../стільки разів, скільки потрібно, щоб піднятися на 2 і більше рівнів.


21
include dirname(__FILE__).'/../../index.php';

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

Дійсно, це змусить включення завжди бути відносно позиції поточного сценарію, де розміщений цей код (яке розташування є, швидше за все, стабільним, оскільки ви визначаєте архітектуру вашого додатка). Це відрізняється від простого виконання, include '../../index.php' яке включатиме відносно виконуючого (також званий "виклик") сценарію, а потім відносно поточного робочого каталогу , який вказуватиме на батьківський скрипт, що включає ваш сценарій, замість того, щоб вирішувати шлях із включеного сценарію .

З документації PHP:

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

І найстаріший допис, який я знайшов із посиланням на цей трюк, датується 2003 роком, Тапкен .

Ви можете протестувати за допомогою наступного налаштування:

Створіть такий макет:

htdocs
¦   parent.php
¦   goal.php
¦
+---sub
    ¦   included.php
    ¦   goal.php

В parent.php, поставте:

<?php
include dirname(__FILE__).'/sub/included.php';
?>

В sub/included.php, поставте:

<?php
print("WRONG : " . realpath('goal.php'));
print("GOOD : " . realpath(dirname(__FILE__).'/goal.php'));
?>

Результат при доступі parent.php:

WRONG : X:\htdocs\goal.php
GOOD : X:\htdocs\sub\goal.php

Як бачимо, у першому випадку шлях вирішується із викликаючого скрипта parent.php, тоді як за допомогою dirname(__FILE__).'/path'трюку включення здійснюється із сценарію, included.phpкуди поміщений код.

Обережно, наступне НЕ еквівалентно трюку вище, на відміну від того, що можна прочитати деінде:

include '/../../index.php';

Справді, попереднє додавання /буде працювати, але воно вирішиться так само, як include ../../index.phpіз скрипта, що викликає (різниця полягає в тому, що include_pathвін не буде розглядатися згодом, якщо він не вдасться). З PHP документ :

Якщо визначено шлях - абсолютний (починаючи з букви диска або \ у Windows, або / в системах Unix / Linux) або відносно поточного каталогу (починаючи з. Або ..) - шлях_включення буде ігноруватися взагалі.


@diEcho: чи можу я знати, чому це "абсолютно неправильно"? Я використовую його для декількох професійних класів, і цей метод насправді єдиний, який працював у кожній ситуації. Це також детально описано в посібнику для php : це не може бути так неправильно.
жахливий

перший рядок абсолютно неправильний. Ви не можете додати ..середину шляху (відносну / абсолютну).
diEcho

@diEcho Я також маю вказати вам на посібник PHP: php.net/manual/en/function.include.php
важкий

скажіть мені один приклад, де ..використовується середина включення. це завжди має бути перша частина включення
diEcho

github.com/lrq3000/dolibarr_customfields/blob/3.2/htdocs/… Професійний модуль для ERP / CRM професійного рівня. Вам, сер, не слід говорити, коли ви не знаєте, що говорите.
скутий

16

../це один каталог. Повторіть для двох каталогів ../../або навіть трьох: ../../../і так далі.

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

Ви можете визначити деякі константи приблизно так:

define('BD', '/home/user/public_html/example/');

define('HTMLBD', 'http://example.com/');

При використанні 'BD' або мого 'базового каталогу' це виглядає так:

file(BD.'location/of/file.php');

define (); посилання




9

Нижче наведено способи доступу до різних каталогів: -

./ = Your current directory
../ = One directory lower
../../ = Two directories lower
../../../ = Three directories lower

7

Ви можете зробити ../../directory/file.txt- це повертає два каталоги назад.

../../../- це три. тощо



6

Але будьте ДУЖЕ обережні, дозволяючи користувачеві вибрати файл. Ви насправді не хочете дозволити їм отримати файл із назвою, наприклад,

../../../../../../../../../../etc/passwd

або інші чутливі системні файли.

(Вибачте, минув деякий час, поки я не працював системою Linux, і, на мою думку, це конфіденційний файл)




4

якщо ви використовуєте php7, ви можете використовувати функцію dirname з параметром рівня 2, наприклад:

dirname("/usr/local/lib", 2);

другий параметр "2" вказує, на скільки рівень вище

посилання на прізвище


3

в тому числі над каталогами може оброблятися проксі-файлом

  • корінь
  • ..... | __веб
  • ..... | ......... | _requiredDbSettings.php
  • ..... |
  • ..... | ___ дб
  • ..... | ......... | _dbsettings.php
  • ..... |
  • ..... | _proxy.php

    dbsettings.php:
    $host='localhost';
    $user='username':
    $pass='pass';
    
    proxy.php:
    include_once 'db/dbsettings.php
    
    requiredDbSettings.php:
    include_once './../proxy.php';

2

Спробуйте ../../. Ви можете змінити його відповідно, оскільки це поверне вас назад на два каталоги. Спочатку перейдіть до кореневого каталогу, а потім перейдіть до потрібного каталогу.

Наприклад, ви знаходитесь root/inc/usr/apі є інший каталог root/2nd/path. Ви можете отримати доступ до pathкаталогу apтаким чином: ../../2nd/pathспочатку перейдіть до кореневого каталогу, ніж бажаний каталог. Якщо не працює, поділіться.


2

якщо ви включите /на початку включення, включення буде сприйнято як шлях від кореня сайту.

якщо ваш веб-сайт http://www.example.com/game/forum/files/index.php, ви можете додати включення до /includes/boot.inc.php, яке дозволить http://www.example.com /includes/boot.inc.php .

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


2

Спробуйте це

цей приклад - один каталог назад

require_once('../images/yourimg.png');

цей приклад - два каталоги назад

require_once('../../images/yourimg.png');

Це точно те саме ;-) Я думаю, ви маєте на увазі "../../images/yourimg.png" на другому?
Едвін

opps свою мою помилку
rajpoot rehan

1

Я побачив ваші відповіді і використовував шлях path із синтаксисом

require_once '../file.php'; // server internal error 500

і сервер http (Apache 2.4.3) повернув внутрішню помилку 500.

Коли я змінив шлях до

require_once '/../file.php'; // OK

все добре.

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