2011-06-14 13 views
7

tengo la siguiente URL ...¿Cómo puedo obtener mod_rewrite para que coincida con una regla de una sola vez

http://localhost/http.mygarble.com/foundationsofwebprogramming/86

... que quiero convertir en lo siguiente:

http://localhost/http.mygarble.com/php/blog.php?subdomain=foundationsofwebprogramming&page=posts&label=86

pensé que podría lograr esto con la siguiente regla:

RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L] 

Sin embargo, lo que encuentro es que esta regla se aplica repetidamente, lo que da como resultado un error interno del servidor. Entiendo que cuando el URI se transforma utilizando esta regla, el URI resultante también coincidirá con la regla y, por lo tanto, se aplica nuevamente ad-infinitum.

Mi comprensión anterior (por cierto confusa) era que la bandera [L] detendría el procesamiento posterior, aunque ahora entiendo que esto simplemente significa que solo el resto de las reglas se omiten, y no detiene la ejecución del motor de reescritura. a través de las reglas de nuevo.

puedo solucionar este problema agregando la siguiente condición ...

RewriteCond $0 !php/blog.php 
RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L] 

... o escribiendo una expresión regular más específico. Pero lo que realmente quiero hacer es encontrar una forma de evitar que el motor de reescritura intente CUALQUIER otra coincidencia una vez que esta regla coincida una vez. es posible?

Muchas gracias.

Respuesta

16

Normalmente se usan 2 métodos.

La primera es una Condición de Reescribir que prueba que el archivo solicitado no es un archivo real. Cuando surge la recursividad interna, tu php/blog.php es un archivo real y la reescritura no se ejecuta la segunda vez. Efecto secundario es que cualquier petición de un fichero que existe no se puede reescribir (que puede ser un buen efecto secundario)

RewriteCond %{REQUEST_FILENAME} !-f 

La segunda solución es comprobar que no estás en una redirección interna con:

RewriteCond %{ENV:REDIRECT_STATUS} ^$ 

El efecto secundario de esta segunda solución es que la rewriteRule no se puede aplicar si se aplican otras reglas antes (si desea ejecutar alguna redirección interna después de una primera pasada de reescritura).

Editar

Para finalizar voy a añadir un tercer método: la [NS] o [nosubreq] etiqueta parece estar haciendo lo mismo. Prevención del uso de reglas después de una redirección interna.

+0

La segunda solución es ideal. Los únicos redireccionamientos que quiero son externos, todas las reglas están destinadas a ejecutarse solo una vez. Gracias amablemente –

+0

Lamentablemente, no tengo la reputación de votar su respuesta, quizás alguien lo haga en mi nombre. Gracias de nuevo. –

+0

@James Smith: no necesitas votar mi respuesta, solo debes "aceptarla" (para que yo tenga el marcado verde). – regilero

4

Y el tercer método es actualizar apache a 2.3.9 o superior y usar el indicador [END] en lugar de [L].

Sin efectos secundarios

Cuestiones relacionadas