#php #relative-path #directory
#php #относительный путь #каталог
Вопрос:
Мне что-то интересно, но, похоже, я не могу найти хороший, четкий ответ или даже решение этой проблемы:
Мой веб-сайт на PHP имеет следующую структуру:
root
functions
generators
helpers
scripts
style
index.php
Это все папки и один файл php. Функции содержат кучу файлов php, связанных с подключением к базе данных и различными другими операциями с базой данных, такими как вставка, удаление, обновление,… Генераторы содержат классы для автоматического создания веб-страниц, чтобы они выглядели одинаково. Помощники — это классы, которые обрабатывают вход в систему, выход из системы, регистрацию и т. Д. Скрипты — это javascript, а стиль — CSS.
В моей папке generators есть файл mainGenerator.php , это создает различные части веб-сайта:
private function generateLogin()
{
if (!isLoggedIn()) {
echo "
<h2>Login</h2>
<form method='post' action='../helpers/login.php' id='loginForm'>
<p>
Username:<br/>
<input class='search' type='text' name='username'/>
Password:<br/>
<input class='search' type='password' name='password'/>
<input name='login' type='image' style='border: 0; margin: 0 0 -9px 5px;' src='style/login.png' alt='Login' title='Login'/><br/>
No account yet? <a href='../register.php'>Register</a>
</p></form>";
} else {
echo "
<h2>Welome, <a href='user.php' style='color: #1293EE;'>" .
$_SESSION['user_name'] .
"</a></h2>
<a href='logout.php'>Log off</a>";
}
}
Этот фрагмент кода генерирует поле входа на каждой странице или отображает приветственное сообщение, если пользователь уже вошел в систему. Как вы можете видеть, действие ссылается на «../helpers/login.php «, потому что это относительное местоположение loginhelper с точки зрения этого генератора.
Теперь, вот проблема: если я нажму кнопку входа в систему на index.php (http://example.com/ProjectName/index.php ) это перенаправляет меня на http://example.com/helpers/login.php и говорит, что файл не найден.
Я вижу, в чем проблема, действие post видит запрос, исходящий от index.php и идет вверх по одному каталогу, а затем ищет /helpers/login.php , которого, конечно, не существует.
Исправлением может быть изменение действия на
action='/helpers/login.php'
но это вызывает у меня ту же проблему, если мне понадобится доступ к generateLogin() из определенного подкаталога…
Как можно решить эту конкретную проблему, т.е. Что ссылка на /helpers/login.php остается корректным, независимо от того, откуда я пытаюсь получить к нему доступ.
Ответ №1:
action='/ProjectName/helpers/login.php'
Предполагая, что ваш корень http://localhost тогда приведенная выше ссылка всегда должна разрешаться следующим образом http://localhost/ProjectName/helpers/login.php независимо от того, вызван ли он из http://localhost/ProjectName/index.php или http://localhost/ProjectName/subdir/index.php
Если вы не хотите жестко кодировать «ProjectName» во многих разных сценариях, вы можете использовать глобальную переменную и определить ее в файле конфигурации:
helpers/ConfigOptions.php:
<?php
$ProjectName = "ProjectName";
?>
Затем в ваших сценариях включите файл конфигурации и используйте определенную вами переменную:
index.php:
include $_SERVER['DOCUMENT_ROOT'] . '/helpers/ConfigOptions.php';
...
echo "
<form action='/$ProjectName/helpers/login.php'>
....
";
Подробнее о DOCUMENT_ROOT:
DOCUMENT_ROOT определяется в файле конфигурации сервера и является корнем файловой системы, в которой выполняются скрипты, а не веб-адресом, который вы вводите в браузере. В приведенном выше примере я предполагаю, что корень документа выглядит примерно как /home/user/www/ProjectName . Если DOCUMENT_ROOT — это только /home/user/www, то вы можете изменить свой путь включения на этот:
include $_SERVER['DOCUMENT_ROOT'] . '/ProjectName/helpers/ConfigOptions.php';
или используйте относительный путь. Мой голос был бы за последнее, так как вам не нужно было бы жестко кодировать «ProjectName».
Таким образом, include() и require() будут принимать либо:
- Абсолютный путь к файлу
- Путь, который относится к текущему исполняемому скрипту. Если A включает в себя B, а B включает в себя C, когда B включает в себя C, он должен предоставить путь, который является относительным к A.
Итак, когда вам нужно использовать DOCUMENT_ROOT? Обычно с шаблонами, где относительный путь, например ../helpers/file.php
, может преобразовываться в разные абсолютные пути в зависимости от того, что включает файл. В приведенном выше примере, где index.php включает в себя ConfigOptions.php , вам, вероятно, не нужно использовать DOCUMENT_ROOT, поскольку index.php это не шаблон. Я все равно использовал его на всякий случай, но, может быть, я открыл здесь целую банку червей. Надеюсь, я не запутал вас еще больше.
Комментарии:
1. Поправьте меня, если я ошибаюсь, но это не работает с requirements, верно? Например, так: включите $_SERVER[‘DOCUMENT_ROOT’] ‘ ./MyProject/helpers/ConfigOptions.php ‘; require_once($ProjectName . ‘/functions/account_fns.php ‘)
2. Это не должно иметь значения, поскольку и include(), и require() принимают относительный или абсолютный путь к файлу. Я обновил свой ответ дополнительной информацией о DOCUMENT_ROOT.
Ответ №2:
Если у вас есть ссылка, начинающаяся с косой черты, она всегда добавляется к корневому каталогу, а не к вашему текущему каталогу…
Итак, если ваша страница есть www.example.com/mySite/foo.html
, и у вас есть такая ссылка: <a href="/bar.html">Bar/<a>
пользователь будет перенаправлен на www.example.com/bar.html
…
У вас должно быть просто действие вашей формы, указывающее на helpers/login.php
Комментарии:
1.
helpers/login.php
будет работать только из каталога верхнего уровня.2. Спасибо за информацию о слэше. Голосую за это!