Apache mod_rewrite одно правило для любого количества возможностей
Я строю довольно большой веб-сайт, и мой .htaccess начинает чувствовать себя немного раздутым, есть способ заменить мою текущую систему - одно правило для каждого из возможного количества варсов, которое можно было бы передать, чтобы один улавливает все выражения, которые могут учитывать различное количество входов?
например, у меня в настоящее время есть:
RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4&$5=$6
RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4
RewriteRule ^([a-z]+)/([^/]*)$ /index.php?mode=$1&id=$2
RewriteRule ^([a-z]+)$ /index.php?mode=$1
первая обратная ссылка всегда является режимом и (если существует больше), вторая всегда является id, после чего любые дополнительные обратные ссылки чередуются между именем входа и его значением
http://www.example.com/search
http://www.example.com/search/3039/sort_by/name_asc/page/23
Мне бы хотелось иметь одно выражение, чтобы изящно обрабатывать все входы.
Ответы
Ответ 1
Похоже на Drupal:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
И затем обработайте все содержимое вашего script, используя php-код, что-то вроде этого
$pathmap = ();
if ($_GET["q"]){
$path = split("/", $_GET["q"]);
for ($i=0; $i+1<count($path); $i++){
$pathmap[$path[$i]] = $path[$i+1];
$i++;
}
}
Ответ 2
Я не знаю, можно ли это сделать с помощью одного выражения, но это можно сделать с помощью фиксированного числа выражений, независимо от того, как долго строка запроса.
Ваши правила mod_rewrite будут вызываться повторно, предоставляя вам то, что иногда называют рекурсией mod_rewrite. Есть способы избежать этого, но я думаю, вы хотите его использовать.
Настроить правило, которое заменяет последнюю пару именем = value &
Держите привязку к строке ввода ввода к выходу. Каждый раз ваша строка запроса будет увеличиваться, а ваш URL будет короче.
В конце концов у вас есть только одно значение, соответствующее вашему последнему правилу.
Вы должны записать строку запроса с помощью
RewriteCond %{QUERY_STRING} ^(.*)$
И затем вы добавляете его обратно к выходу с помощью% 1
У вас будет четыре строки.
Я знаю, что четыре строки - это то, с чего вы начали, но вы должны соответствовать столько параметров, сколько хотите, не добавляя пятую строку.
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*/)([^/]+)/([^/]+) $1?$2=$3&%1 [L]
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^([^/]+)/ $1.php?%1 [L]
Это приведет к перезаписи следующих
/mypage/param1/val1/param2/val2/param3/val3/... --->
/mypage.php?param1=val1¶m2=val2¶m3=val3&...
Он останавливается, когда остается только один параметр. Он примет первый "параметр" и вызовет файл .php с этим именем. Число пар param/val не ограничено.
Ответ 3
Я не верю, что это путь, но я бы сказал, что лучше всего будет иметь script "index.php" путь, а не делать так много обратных ссылок.
Так, например, ваш rewriterule будет
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Или аналогично... Это затем приведет к тому, что переменная $_SERVER ['REQUEST_URI'] содержит информацию о пути, которую вы можете разделить и проанализировать.
$path = split('/', $_SERVER['REQUEST_URI']);
array_shift($path); // We always have a first null value
$mode = array_shift($path);
В результате получается $mode, содержащий режим, и $path, содержащий массив элементов, которые являются остальной частью вашего пути, поэтому
http://example.com/foo/bar/baz
Оставил бы вас с $mode: 'foo' и $path - массив, содержащий 'bar' и 'baz'