Абсолютный URL из базовой папки с перезаписью

У меня есть проект, работающий локально на WampServer. Это MVC-подобная структура; переписывает URL index.php?url=$1, Полный .htaccess:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

Когда я хочу отправить пользователя на другую страницу, используя PHP location: <location> это не делает это должным образом из-за переписывания (все-хотя я технически всегда в index.php).

Например, если я нахожусь на http://localhost/project_name/controller/method/ и конструктор или метод этого контроллера пытается отправить меня к:

  • header('location: another_controller/method'); отправляет меня в
    http://localhost/project_name/controller/method/another_controller/method/
  • header('location: /another_controller/method'); отправляет меня в
    http://localhost/another_controller/method/

Но я хочу, чтобы он отправил меня так:

  • header('location: /another_controller/method'); отправляет меня в
    http://localhost/project_name/another_controller/method/

Теперь единственное решение, которое я нашел, это:

define('BASE_URL','http://localhost/project_name');
header('location: '.BASE_URL.'/another_controller/method/');

Но это также не идеально, потому что это заставляет меня изменить эту определенную константу BASE_URL всякий раз, когда меняется имя домена или папки. Я мог бы также создать метод в моем BaseController который создает абсолютные URL, но этот метод в основном просто предваряет BASE_URL тоже.

Замечания: Та же проблема не возникает с HTML src а также href атрибуты, которые могут использовать относительные пути (без project_name папка в пути). Однако я не понимаю, почему. Потому что, если заголовок location заставляет браузер добавлять относительный URL к текущему местоположению, почему при поиске он не работает так же .css или же .js файлы.

Так… это поднимает пару вопросов для меня:

  1. Буду ли я иметь эту проблему, если бы у меня были виртуальные хосты?
  2. Как лучше всего решить эту проблему?
  3. Лучше всего просто иметь полный абсолютный URL?
  4. Почему HTML src а также href атрибуты не разделяют это поведение?

11

Решение

Теперь единственное решение, которое я нашел, это:

define('BASE_URL','http://localhost/project_name');
header('location: '.BASE_URL.'/another_controller/method/');

Но это тоже не идеально, потому что это заставляет меня менять
это определенная константа BASE_URL всякий раз, когда имя домена или папки
изменения.

Вам не нужно менять определенную константу. Эти значения могут быть найдены динамически.

Пример:

if ($_SERVER['DOCUMENT_ROOT'] == dirname($_SERVER['SCRIPT_FILENAME'])) {
define('BASE_PATH', '/');
} else {
define('BASE_PATH', dirname($_SERVER['SCRIPT_NAME']) . '/');
}

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
define('BASE_URL', $protocol . $_SERVER['SERVER_NAME'] . BASE_PATH);

Кроме того, вместо того, чтобы беспокоиться о том, указывать ли абсолютный URL или путь, вы можете заключить перенаправление в функцию, которая может обрабатывать оба:

function redirect($path = null) {
if (isset($path)) {
if (filter_var($path, FILTER_VALIDATE_URL)) {
header('Location: ' . $path);
} else {
header('Location: ' . BASE_URL . $path);
}
} else {
header('Location: ' . BASE_URL);
}
exit;
}

Наконец, как отметил @HarshSanghani в комментариях, базовый путь в вашем .htaccess файл должен сопоставьте базовый путь в вашем коде. Так что если BASE_PATH (на основе приведенного выше примера) /project_name/тогда ваш .htaccess следует учесть это:

RewriteBase /project_name/
4

Другие решения

Чтобы ответить на ваши вопросы:

  1. Это зависит от того, как будут настроены ваши виртуальные хосты.
  2. Вы можете просто сгенерировать свой BASE_URL динамически: $baseUrl = dirname($_SERVER['SCRIPT_NAME']);, Таким образом, вам не придется менять код, если ваша папка или домен изменятся.
  3. Вам не нужна доменная часть.
  4. HTML src а также href интерпретируются вашим браузером, который учитывает <base> тег. Все пути на странице с <base> тэг изменяется соответственно вашим браузером.

Заголовки HTTP, которые вы отправляете со своего сервера (для перенаправления), не имеют ничего общего с отправляемой вами HTML-страницей и поэтому не обновляются.

2

  1. Вы столкнетесь с этой проблемой, если ваш проект настроен в подкаталоге. Использование виртуальных хостов будет способом решения этой проблемы, если вы захотите настроить их, скажем, project_name.localhost.
  2. В своих проектах я использую переменную среды для загрузки другого файла конфигурации для разработки, подготовки или производства. В этом я поставил $baseUri как-то.
  3. Рекомендуется использовать абсолютные URL-адреса (включая домен) как для решения этой проблемы, так и для SEO. С точки зрения функциональности вам не нужна доменная часть.
  4. Теги src и href обычно работают одинаково, но, как отметил Андреас, базовый тег может повлиять на них.
2

Вы должны указать RewriteBase в вашем файле htaccess. Используйте относительные пути в своих ссылках, и вам больше ничего не нужно.

RewriteBase /project_name/
RewriteEngine on
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector