#php #.htaccess
#php #.htaccess
Вопрос:
У меня есть пользовательский фреймворк PHP, в котором все после домена отправляется на PHP в виде переменной $ _GET, например:
RewriteRule ^(.*)$ index.php?page_request=$1 [QSA,L]
Вся маршрутизация выполняется файлом маршрутизатора. Например, http://domain.tld/page
отправляется на http://domain.tld?page_request=home
.
Однако, если у меня есть структура, подобная каталогу (т. Е. http://domain.tld/page/
), Запрос отправляется, но любые относительные URL-адреса в HTML теперь относятся к /page
, даже если мы все еще находимся на корневом уровне в домене.
Чтобы уточнить:
Переход http://domain.tld/page
и запрос res/css/style.css
в HTML возвращает таблицу стилей.
Переход http://domain.tld/page/
и запрос res/css/style.css
возвращает ошибку 404, поскольку page/
каталог фактически не существует.
Каков наилучший способ обойти это? Это кажется действительно простым, но я еще недостаточно хорошо разбираюсь в .htaccess, чтобы делать это с головы до ног. Заранее спасибо за любые ответы.
Редактировать: кроме того, мой файл .htaccess содержит:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Редактировать # 2: Да, я знаю об использовании ведущего / .
Однако я не могу сделать это с этим конкретным веб-сайтом, потому что это подпапка на сервере, поэтому ссылка на /
будет идти в корень сервера, а не на сайт.
Если бы я помещал /subfolder/css
для каждой ссылки на сайте, это было бы не только утомительно, но и проблематично, если бы нужно было изменить вложенную папку. Есть ли лучший способ обойти это?
Ответ №1:
Другие ответы, в которых говорится, что вам нужно абсолютизировать пути, верны. Если вы работаете во вложенной папке, есть две вещи, которые вы можете / должны сделать, чтобы помочь:
1) Используйте RewriteBase
в вашем файле htaccess
RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/?$ index.php?url=$1 [QSA,L]
2) Создайте константу в своей среде, которая имеет тот же путь
define('FULL_PATH', '/framework');
Затем каждый раз, когда вы создаете URL-адрес в html, убедитесь, что вы делаете что-то вроде
<a href="<?= FULL_PATH ?>/your/remaining/path">
Думать об этом каждый раз, когда вы создаете URL-адрес на странице, требует немного дополнительной работы, но в долгосрочной перспективе это сослужит вам хорошую службу.
Ответ №2:
Правила перезаписи apache не влияют на относительные URL-адреса. Они зависят от браузера. Если браузер отправляет запрос на /some/random/path/
, вы можете переписать его сколько угодно на стороне сервера, но браузер будет интерпретировать все относительные URL-адреса как находящиеся внутри /some/random/path/
Если вы хотите включить res/css/style.css
из корня, вы должны добавить к нему косую черту, чтобы это было ясно: /res/css/style.css
Комментарии:
1. Я знаю, что Apache не влияет на относительные URL-адреса, но я включил .htaccess, потому что именно это вызывает проблему. Я не могу использовать начальную косую черту, потому что сайт находится во вложенной папке.
2. Вы должны по этой причине, вы можете предшествовать ссылкам с помощью /subfolder/ … в противном случае это единственный способ, которым браузеры найдут правильное содержимое, когда ваши правила перезаписи выглядят как URL-адреса каталогов / файлов.
3. Есть ли какой-нибудь способ обойти это? Кажется повторяющимся / не СУХИМ делать это для каждого URL-адреса на сайте.
4. Я не вижу другого пути. Если вы выводите свой html с помощью шаблонов или с помощью PHP, вы можете установить глобальную переменную like
define('BASE_URL', 'http://yoursite.com/subfolder');
, а затем вернуть какую-либо функцию, подобнуюget_url('css/main/style.css');
той, которая будет возвращатьhttp://yoursite.com/subfolder/css/main/style.css
, чтобы вы могли использовать эту функцию везде.
Ответ №3:
Если вы ищете динамическое решение (в случае, если вы перемещаете весь сайт во вложенную папку или другой домен), вы можете использовать PHP, чтобы получить абсолютный путь к файлу, который вы запускаете (например, к вашему основному php-файлу), а затем сохранить этот путь в константе или переменной, которую вы можете использоватьдля всех ваших ссылок.
if ( !isset($_SERVER['HTTPS']) ) { $domain = 'http://'.$_SERVER['HTTP_HOST']; }
else { $domain = 'https://'.$_SERVER['HTTP_HOST']; };
$root = $domain.str_replace($_SERVER['DOCUMENT_ROOT'], '', dirname(__FILE__) );
Первые две строки просто настраивают, как будет начинаться путь, должен ли он быть http или https.
Третья строка получает полный путь сервера к файлу, в котором находится этот код, удаляет ненужные части (user / public_html) и сохраняет его в переменной $root .
Затем вы можете связать свои файлы таким образом:
<script src=»<?php echo $root; ?>/jquery.js «></script>
С помощью этого метода сайт можно переместить в любой домен или подпапку, и вам не нужно беспокоиться о разрыве ссылок.
Редактировать: я просто подумал о более простом способе использования этого метода. Вместо того, чтобы использовать абсолютные ссылки, вы можете использовать свои обычные относительные ссылки вместе с этим в заголовке документа:
<base href="<?php echo $root; ?>/">
Это переписывает базовый путь для ваших относительных ссылок в правильный каталог. Тогда это будет работать:
<script src="jquery.js"></script>
Ответ №4:
Вам нужно абсолютизировать все пути в вашем html-коде, чтобы вы ссылались на свой CSS, используя абсолютные пути вместо относительных.
Если вы столкнулись с этой проблемой, я подозреваю, что ваш CSS выглядит следующим образом:
<link href="res/css/style.css" rel="stylesheet" type="text/css" media="screen" />
Но это должно выглядеть так:
<link href="/res/css/style.css" rel="stylesheet" type="text/css" media="screen" />
Сделайте то же самое для javascript, css, файлов изображений и ссылок, и вы должны быть в порядке с вашими правилами перезаписи.
Комментарии:
1. Спасибо, я знал о начале косой черты, но см. Мой Отредактированный вопрос выше.
2. Сделайте /subfolder/content/, и это сработает. Единственная «проблема» заключается в том, что если вы когда-нибудь переместите свой сайт, вам, возможно, придется отредактировать много путей, но вы можете использовать /subfolder/css вместо просто /css