2008-09-22 14 views
11

Estoy construyendo un sitio web bastante grande y mi .htaccess está empezando a sentirse un poco hinchado, ¿hay alguna manera de reemplazar mi sistema actual de - una regla para cada uno de los posibles número de vars que se pueden pasar, ¿se puede capturar toda la expresión que puede representar un número variable de entradas?apache mod_rewrite una regla para cualquier cantidad de posibilidades

por ejemplo Actualmente tengo:

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 

la primera referencia inversa es siempre el modo y (si la hay más existe) la segunda es siempre Identificación del, a partir de entonces más lejos backreferences alternan entre el nombre de la entrada y su valor

http://www.example.com/search 
http://www.example.com/search/3039/sort_by/name_asc/page/23 

me gustaría ser capaz de tener una expresión manipular con gusto todas las entradas.

+0

Eso no está hinchado :) Deberías haber visto algunas de mis configuraciones de Apache. En serio, 4 líneas de regla de reescritura es perfectamente razonable. – Aeon

+0

esto es solo una sección de mi configuración que sentí que podía mejorar, pero no estaba seguro de cómo, hay otras secciones en las que estoy trabajando actualmente;) – JimmyJ

Respuesta

8

hacer como Drupal:

RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] 

Y luego manejar todas las cosas en su secuencia de comandos mediante código php algo como esto

$pathmap =(); 
if ($_GET["q"]){ 
    $path = split("/", $_GET["q"]); 
    for ($i=0; $i+1<count($path); $i++){ 
     $pathmap[$path[$i]] = $path[$i+1]; 
     $i++; 
    } 
} 
+0

no es exactamente lo que estaba buscando pero una buena alternativa no obstante – JimmyJ

+0

¿Cómo ¿manejas esto en el script más tarde? –

2

no creo que su es una manera - pero Diría que su mejor opción sería hacer que el script "index.php" procese una ruta en lugar de tener que hacer tantas referencias atrás.

Así, por ejemplo, su RewriteRule sería

RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule . /index.php [L] 

o similares ... Esto entonces hacer el [ 'REQUEST_URI'] variable $ _SERVER contiene la información de ruta, que se puede dividir y analizar.

$path = split('/', $_SERVER['REQUEST_URI']); 
array_shift($path); // We always have a first null value 
$mode = array_shift($path); 

Esto termina con el modo de $ que contiene el modo y la ruta $ contiene una serie de elementos que son el resto de su trayectoria, por lo

http://example.com/foo/bar/baz 

¿Quieres que deje de ser el modo de $ foo 'y $ path es una matriz que contiene' bar 'y' baz '

+0

No funciona del modo esperado porque $ _SERVER ['REQUEST_FILENAME'] debe ser $ _SERVER ['REQUEST_URI'] y el modo $ siempre está vacío. El principio es bueno sin embargo. – da5id

+0

Resolvió los problemas que señaló – Mez

7

No sé si se puede hacer con una sola expresión, pero se puede hacer con un número fijo de expresiones, sin importar cuánto tiempo la cadena de consulta.

Se invocarán repetidamente las reglas de tu mod_rewrite, lo que a veces se denomina recursividad mod_rewrite. Existen técnicas para evitarlo, pero creo que quieres usarlo.

establecer una regla que reemplaza el último par con el nombre = valor &

Mantener viradas en la cadena de consulta de entrada a la salida. Cada vez que lo haga, su cadena de consulta será más larga y su URL será más corta.

Finalmente, solo tiene un valor único que coincida con su última regla.

tienes que capturar la cadena de consulta con

RewriteCond %{QUERY_STRING} ^(.*)$ 

a continuación, agregar de nuevo a la salida con 1%

Terminarías con cuatro líneas.

Sé que cuatro líneas es lo que comenzaste, pero coincidirías con todos los parámetros que quisieras sin tener que agregar una quinta línea.

RewriteCond %{QUERY_STRING} ^(.*)$ 
RewriteRule ^(.*/)([^/]+)/([^/]+) $1?$2=$3&%1 [L] 
RewriteCond %{QUERY_STRING} ^(.*)$ 
RewriteRule ^([^/]+)/ $1.php?%1 [L] 

Esto reescribir la siguiente

/mypage/param1/val1/param2/val2/param3/val3/...  ---> 
/mypage.php?param1=val1&param2=val2&param3=val3&... 

Se detiene cuando sólo hay un parámetro restante. Tomará el primer "parámetro" y llamará al archivo .php con ese nombre. No hay límite para la cantidad de pares param/val.

+0

Gracias por este comentario. Ciertamente ayudó a otra pregunta (no en SO). –

Cuestiones relacionadas