Подтвердить что ты не робот

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

Мне бы хотелось иметь одно выражение, чтобы изящно обрабатывать все входы.

4b9b3361

Ответ 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&param2=val2&param3=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'