rewriterule mod_rewrite htaccess examples apache mod-rewrite url-rewriting

apache - mod_rewrite - Reescribir una cantidad arbitraria de segmentos de ruta para consultar parámetros



mod_rewrite apache2 debian (2)

Tengo esta regla de .htaccess:

RewriteRule viewshoplatest/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/$ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

Debe mapear una URL como esta:

http://www.veepiz.com/viewshoplatest/start/10/end/10/filter/0/ownerid/0/sortby/date/sortdir/DESC/cat/0/scat/0/

a esto:

http://www.veepiz.com/viewshoplatest.php?start=0&end=10&filter=0&ownerid=0&sortby=date&sortdir=DESC&cat=0&scat=0

Cuando hago clic en el enlace e $_GET variables $_GET obtengo esto:

Array ( [start] => 10 [end] => 10 [filter] => 0 [ownerid] => 0 [sortby] => start0 [start1] => start2 [start3] => start4 [start5] => start6 )

¿Alguna idea de por qué se está comportando mal?

Ok, lo arreglé reescribiendo la regla para

RewriteRule viewshoplatest/start/(.*)/end/(.*)/filter/(.*)/ownerid/(.*)/sortby/(.*)/sortdir/(.*)/cat/(.*)/scat/(.*)/$ /viewshoplatest.php?start=$1&end=$2&filter=$3&ownerid=$4&sortby=$5&sortdir=$6&cat=$7&scat=$8


Solo para ampliar lo que descubrió, solo puede definir nueve grupos para usar como referencias, por lo que generalmente es una mejor idea reescribir en una cadena sans-query de scripts y hacer que la secuencia de comandos examine REQUEST_URI en los casos en que tenga una gran cantidad de datos para analizar.

De la documentación :

Las referencias retros son identificadores de la forma $ N (N = 0..9), que serán reemplazados por los contenidos del N-ésimo grupo del Patrón coincidente

$0 es el patrón combinado completo, que le da los nueve números restantes para trabajar. Cualquier número más alto se trata como una referencia inversa seguida de algunos caracteres numéricos literales.


Antes que nada: no debe usar .* Si puede ser más específico, como en este caso [^/]+ . Porque multiple .* Puede causar un inmenso retroceso. Asi que:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

Puede usar una toma como RegexBuddy para ver la diferencia en cómo se procesan estas expresiones regulares.

Pero como mod_rewrite solo permite hacer referencia a los primeros nueve grupos (ver la respuesta de Tim ), puede usar un enfoque iterativo y procesar un parámetro a la vez:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+/[^/]+/.*)$ /viewshoplatest/$3?$1=$2 [QSA,N] RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]*)/?$ /viewshoplatest.php?$1=$2&$3 [QSA,L]

La primera regla procesará un par de parámetros a la vez (excepto el último par) agregándolo a los ya existentes (ver indicador QSA ) y luego reiniciará el proceso de reescritura sin incrementar el contador interno de recursión (ver indicador N ). La segunda regla reescribirá el último par de parámetros (o solo el nombre) y finalizará la iteración.

Pero dado que usar la bandera N puede ser peligroso ya que puede causar una recursión infinita, también puede usar PHP para analizar la ruta solicitada:

$_SERVER[''REQUEST_URI_PATH''] = parse_url($_SERVER[''REQUEST_URI''], PHP_URL_PATH); $segments = implode(''/'', trim($_SERVER[''REQUEST_URI_PATH''], ''/'')); array_shift($segments); // remove path prefix "/viewshoplatest" for ($i=0, $n=count($segments); $i<$n; ) { $_GET[rawurldecode($segments[$i++])] = ($i < $n) ? rawurldecode($segments[$i++]) : null; }

Ahora solo necesita esta regla para pasar la solicitud a través de:

RewriteRule ^viewshoplatest(/|$) /viewshoplatest.php [L]