Mod_rewrite для всех страниц (включая подпапки) на сайте на одну php-страницу

Я собираюсь преобразовать свой сайт со многими статическими html-страницами на сайт, управляемый базой данных. Моя проблема заключается в том, что я не хочу потерять то, что уже проиндексировал Google, поэтому я хотел бы переписать запросы, отправляемые через php script, которые ищут путь к файлу для содержимого в базе данных. Я понимаю, что 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

Идеи? Спасибо заранее:)

Edit:

Итак, я попытался реализовать решение Ragnar, но я продолжал получать 500 ошибок, когда я использую "RewriteCond $1" или включаю "/" в последней строке. Я установил файл test.php, который будет эхо GET _ [ "page" ], поэтому я знаю, что переписывание работает правильно. До сих пор я могу получить некоторые правильные результаты (но только когда я не в корне), например:

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 script. Окончательное решение для работы с тем, что я хочу, следующее:

Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test.php

Тогда в моем php script я могу использовать $_SERVER ['REQUEST_URI'], чтобы получить то, что мне нужно. Я знал, что это должно быть проще, чем то, что я пытался...

Ответ 1

Я бы порекомендовал вам заглянуть в Руководство по перезаписи URL-адресов Apache, он содержит обширную информацию о перезаписи с примерами.

Если вы правильно поняли, вы должны использовать что-то вроде этого

RewriteEngine on
RewriteCond $1 
RewriteRule ^(.*)$ index.php/?page=$1 [L]

Который очень похож на тот, который вы опубликовали. Если вам нужна более подробная информация, будьте конкретны в своей проблеме.

Ответ 2

Нет необходимости в стольких строках, это только усложняет ситуацию.

Все, что вам нужно, это 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

Вы можете вывести первый ввод перезаписи в PHP, используя:

<?=$_SERVER['REQUEST_URI'];

Это даст вам всю силу и позволит вам делать все. Просто проанализируйте $_SERVER["REQUEST_URI"] вручную, и вы можете echo полностью разные страницы в зависимости от значения $_SERVER["REQUEST_URI"].


Блокировка

Обратите внимание, что ваш сервер может выполнять pathing или buggy pathing до перезаписывания. (Вы не можете переопределить это поведение без привилегий сервера.) Например, если пользователь посещает /foo////, вы можете видеть только /foo/ или /foo. И, например, если пользователь посещает ///foo, вы можете видеть только /foo. Например, если пользователь посещает /a/../foo, вы можете видеть только /foo. И, например, если пользователь посещает /a//b/../../foo, вы можете видеть только /foo или /a/foo [потому что багги-серверы обрабатывают несколько / в отличие от .., без шуток].


С отключением цепи

Rewrite circuit breaks on cin identical to htaccess∙parentfolder∙relative interpreted rewriterule∙arg2. (First off, personally I'd disable circuit breaks to reduce rule complexity but there seems to be no way to do so.)

Решение кругового разрыва:

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 [rewriterule] & rlhar; абсолют. и htaccess parentfolder & rlhar; корень.
  • arg2 & rlhar; относительный. и эта папка не в интерпретируемой arg2.

So when that folder ≠ root, circuit break needs arg2 &rlhar; relative. when arg2 &rlhar; relative, circuit break needs⎾that folder &rlhar; not in interpreted 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