mod_rewrite для всех страниц (включая подпапки) сайта на одной странице php
Я нахожусь в процессе преобразования моего сайта со многими статическими HTML-страницами в сайт, управляемый базой данных. Моя проблема в том, что я не хочу потерять то, что Google уже проиндексировал, поэтому я хотел бы переписать запросы, которые будут отправлены через скрипт php, который ищет путь к файлу для содержимого в базе данных. Насколько я понимаю, mod_rewrite лучше всего подходит для этой цели, к сожалению, я никогда не использовал его, поэтому я немного растерялся.
Что я имею:
www.domain.com/index.html
www.domain.com/page.html?var=123&flag=true
www.domain.com/folder/subfolder/
www.domain.com/folder/subfolder/index.html
www.domain.com/folder/subfolder/new/test.html
www.domain.com/folder/subfolder/new/test.html?var=123&flag=true
Что я хочу (мне также, вероятно, нужно urlencode путь)(передача полного URI тоже нормально):
www.domain.com/index.php?page=/index.html OR www.domain.com/index.php?page=www.domain.com/index.html
www.domain.com/index.php?page=/page.html?var=123&flag=true
www.domain.com/index.php?page=/folder/subfolder/
www.domain.com/index.php?page=/folder/subfolder/index.html
www.domain.com/index.php?page=/folder/subfolder/new/test.html
www.domain.com/index.php?page=/folder/subfolder/new/test.html?var=123&flag=true
Вот мой первый опыт:
RewriteEngine On # Turn on rewriting
RewriteCond %{REQUEST_URI} .* # Do I even need this?
^(.*)$ /index.php?page=$1
Идеи? Заранее спасибо:)
Редактировать:
Поэтому я попытался реализовать решение Ragnar, но получал 500 ошибок, когда я использовал 'RewriteCond $1' или включал '/' в последнюю строку. Я настроил файл test.php, который будет отображать GET_["page"], поэтому я знаю, что перезапись работает правильно. До сих пор я могу получить некоторые правильные результаты (но только когда я не в root), например:
RewriteEngine on
RewriteRule ^page/(.*)$ test.php?page=$1 [L]
Если я захожу на страницу http://www.domain.com/page/test/subdirectory/page.html?var=123 то выдается "test / subdirectory / page.html" (отсутствует строка запроса, которая мне нужна). Однако, если я использую этот пример:
RewriteEngine on
RewriteRule ^(.*)$ test.php?page=$1 [L]
Если я зайду на сайт http://www.domain.com/page/test/subdirectory/page.html?var=123 он выдаст только test.php, что сильно сбивает с толку. Мысли?
Редактировать № 2:
Кажется, я все об этом говорил неправильно. Я просто хотел иметь возможность использовать полный URI на моей странице сценария php. Последнее, что я хочу сделать, это следующее:
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test.php
Затем в своем php-скрипте я могу использовать $_SERVER['REQUEST_URI'], чтобы получить то, что мне нужно. Я знал, что это должно было быть проще, чем то, что я пытался...
2 ответа
Я бы порекомендовал вам ознакомиться с Руководством по перезаписи URL-адресов Apache, в котором содержится обширная информация о перезаписи с примерами.
Если я вас правильно понимаю, вы сможете использовать что-то вроде этого
RewriteEngine on
RewriteCond $1
RewriteRule ^(.*)$ index.php/?page=$1 [L]
Какой код очень похож на тот, который вы опубликовали. Если вам нужна более качественная информация, будьте конкретны в отношении вашей проблемы.
Там не нужно так много строк, это только усложняет вещи.
Все, что вам нужно, это 2 строки в .htaccess
:
rewriteengine on
#rewriterule-: ar1 path =relative. ar2 if relative, that to rewritebase.
rewriterule !^foo/bar/index\.php$ /foo/bar/index.php
#..assert ar1 dismatches correct url
В PHP
Вы можете вывести первый ввод rewriterule в PHP, используя:
<?=$_SERVER['REQUEST_URI'];
Это даст вам всю силу и позволит вам делать все. Просто разобрать $_SERVER["REQUEST_URI"]
вручную, и вы можете echo
совершенно разные страницы в зависимости от стоимости $_SERVER["REQUEST_URI"]
,
Sec ошибки
Обратите внимание, что ваш сервер может делать пути или глючить пути перед перезаписью. (Вы не можете переопределить это поведение без привилегий сервера.) Например, если пользователь посещает /foo////
вы можете видеть только /foo/
или же /foo
, И, например, если пользователь посещает ///foo
вы можете видеть только /foo
, И, например, если пользователь посещает /a/../foo
вы можете видеть только /foo
, И, например, если пользователь посещает /a//b/../../foo
вы можете видеть только /foo
или же /a/foo
[потому что ошибочные производственные серверы обрабатывают несколько /
как отличается в контексте ..
Без шуток.
С разрывом цепи
Переписать разрывы цепей на cin, идентичные htaccess ∙ родительская папка ∙ относительная интерпретация rewriterule ∙ arg2. (Во-первых, лично я отключил бы прерывания цепи, чтобы уменьшить сложность правил, но, похоже, нет никакого способа сделать это.)
Прерывание цепи:
rewriteengine on
#rewriterule-: ar1 path =relative. ar2 if relative, that to rewritebase.
rewriterule ^ /foo/bar/index.php
#..circuit-breaking, so assert ar2 if absolute, htaccess parentfolder =root, else, htaccess parentfolder not in interpreted ar2.
Обрыв цепи и перезапись незапланированного использования
Для отключения цепи необходимо:
- arg2 [of rewriterule] ⇌ абсолют. и родительская папка htaccess ⇌ root.
- arg2 ⇌ относительный. и эта папка не в интерпретируемом arg2.
Поэтому, когда эта папка ≠ root, разрыв цепи требует относительного arg2 ⇌. когда arg2 ⇌ относительный, для разрыва цепи требуется "эта папка", а не в интерпретируемом arg2⏋.
Скажем, нам нужен разрыв цепи и родительская папка htaccess, которая находится в интерпретируемом arg2, поэтому мы редактируем arg2 через rewritebase:
rewriteengine on
#rewriterule-: ar1 path =relative. ar2 if relative, that to rewritebase.
rewriterule ^ bar/index.php
#..circuit-breaking, so assert ar2 if absolute, htaccess parentfolder =root, else, htaccess parentfolder not in interpreted ar2.
rewritebase /foo
#..needs to be absolute [</> starting]. pathing [eg </../a/..> and </../..///ran/dom-f/oobar/./././../../..////////.//.>] allowed