Как получить исходный путь символьной ссылки в PHP?
У меня есть несколько файлов в моей веб-папке, в том числе эти два:
- /mydocroot / include / somesubdir / include.инк.php
- /mydocroot / include / settings.инк.php
Гдеsomesubdir - это символическая ссылка на другой каталог на моем диске, на путь с именем, скажем, /anywhere/else .
Внутри включить.инк.php , что-то вроде этого написано:
<?php
require_once "../settings.inc.php";
?>
На мой взгляд, это должно включать /mydocroot / include / settings.php ... Но угадайте, что происходит: PHP пытается включить / anywhere / settings.инк.php, вместо того, чтобы /mydocroot / include / settings.инк.php .
Похоже, что PHP автоматически разрешает символьные ссылки.
Как я могу избежать этого и включить Мои настройки .инк.php файл?
4 ответа:
Самое простое решение-всегда использовать абсолютные пути. Есть несколько способов сделать это, от жесткого кодирования пути каждый раз, когда он вам нужен, до жесткого кодирования пути один раз в верхней части вашего сценария и ссылки на него, до динамического определения его и установки его один раз в верхней части вашего сценария.
Третий вариант - это то, что большинство готовых CMSs используют, чтобы иметь возможность работать без полного знания вашей файловой структуры.Почему вы используете символически связанный каталог таким образом?
У меня только что была похожая проблема. Вы можете сделать это с помощью переменной
$_SERVER['SCRIPT_FILENAME']
, которая отображает запрошенный файл, поэтому в вашем случае это будет/mydocroot/include/somesubdir/include.inc.php
, даже еслиsomesubdir
является символьной ссылкой. Включить файл, который находится на один уровень ниже, вместо того, чтобы делатьrequire_once "../settings.inc.php";
Сделайте так:
require_once dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR."settings.inc.php"
Решение заключается в создании переменной basepath. Лучший способ сделать это-включить следующее в верхней части вашего сценария и затем ссылаться на него
$basepath = dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR;
Затем вы можете ссылаться на базовый путь в своих includes, requires и т. д. Поэтому
include "../myscript.php";
Стал бы,
include $basepath."myscript.php";
Если вы снова тикаете дальше, у вас будет это:
include "../../myscript.php";
Стал бы,
include $basepath."../myscript.php";
Вы должны вложить функции dir_name дважды, плюс еще один раз для каждой дополнительной папки тебе нужно вернуться назад. Вы должны полностью вернуться к папке, в которой существует символическая ссылка.
Я считаю этот вопрос главным недостатком дизайна PHP. Я не могу придумать ни одного случая, когда был бы желателен доступ к обратным файлам относительно фактического файла. Во всех ситуациях, включая виртуальный хостинг, имеет смысл только регрессировать назад по связанному пути, но никогда по целевому пути.
Вы можете использовать
Но за десять лет разработки php у меня никогда не было повода использовать символические ссылки. Как предполагает Джейсон, я всегда определял или выводил абсолютный путь один раз, а затем использовал его в своем приложении, чтобы сделать все пути к файлам абсолютными.is_link
чтобы проверить, является ли файл символьной ссылкой. Если это так, используйтеreadlink
чтобы получить абсолютную цель.