Как получить исходный путь символической ссылки в PHP? - PullRequest
7 голосов
/ 16 марта 2012

В моей веб-папке есть несколько файлов, включая эти два:

  • / mydocroot / include / somesubdir / include.inc.php
  • / mydocroot / include / settings.inc.php

где somesubdir - это символическая ссылка на другой каталог на моем диске, на путь с именем, скажем, /where / else .

Внутри include.inc.php , примерно так написано:

<?php

require_once "../settings.inc.php";

?>

По моему мнению, должно включать / mydocroot / include / settings.php ... Но угадайте, что произойдет: PHP пытается включить /where / settings.inc.php , вместо /mydocroot/include/settings.inc.php.

Похоже, PHP автоматически разрешает символические ссылки.

Как мне избежать этого и включить мои settings.inc.php file?

Ответы [ 4 ]

3 голосов
/ 25 июля 2012

У меня просто была похожая проблема. Вы можете сделать это с помощью переменной $_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"

Документация по $_SERVER переменным

2 голосов
/ 16 марта 2012

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

Третий вариант - это то, что большинство готовых CMS используют для запуска без полного знания вашей файловой структуры.

Почему вы используете символически связанный каталог таким образом?

1 голос
/ 11 января 2013

Решение - создать переменную basepath. Лучший способ сделать это - включить следующее в начало вашего скрипта, а затем сослаться на него

$basepath = dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR;

Затем вы можете ссылаться на базовый путь в ваших включениях, требованиях и т. Д. Следовательно,

include "../myscript.php";

станет,

include $basepath."myscript.php";

Если вы вернетесь дальше, у вас будет следующее:

include "../../myscript.php";

станет,

include $basepath."../myscript.php";

Вы должны вложить функции dir_name дважды, плюс еще один раз для каждой дополнительной папки, через которую вы хотите вернуться назад. Вы ДОЛЖНЫ пройти весь путь до папки, где существует символическая ссылка.

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

0 голосов
/ 16 марта 2012

Вы можете использовать is_link, чтобы проверить, является ли файл символической ссылкой.Если это так, используйте readlink, чтобы получить абсолютную цель.

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

...