относительные пути и каталоги php

#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() будут принимать либо:

  1. Абсолютный путь к файлу
  2. Путь, который относится к текущему исполняемому скрипту. Если 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. Спасибо за информацию о слэше. Голосую за это!