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.

Обрыв цепи и перезапись незапланированного использования

Для отключения цепи необходимо:

  1. arg2 [of rewriterule] ⇌ абсолют. и родительская папка htaccess ⇌ root.
  2. 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
Другие вопросы по тегам