2009-02-27 14 views
14

Espero que haya una manera de hacer esto con mod_rewrite y Apache, pero tal vez hay otra manera de considerarlo también.¿Redirige las solicitudes solo si no se encuentra el archivo?

En mi sitio, tengo directorios configurados para versiones rediseñadas del sitio para clientes. Si la raíz web es /home/blah/www, un directorio de cliente sería /home/blah/www/clients/abc. Cuando accede al directorio del cliente a través de un navegador web, quiero que use los archivos solicitados en el directorio del cliente, si es que existen. De lo contrario, quiero que use el archivo en la raíz web.

Por ejemplo, supongamos que el cliente no necesita su propio index.html. Por lo tanto, algún código determinaría que no hay index.html en /home/blah/www/clients/abc y, en su lugar, usará el de /home/blah/www. Tenga en cuenta que no quiero redirigir al cliente a la raíz web en ningún momento, solo quiero utilizar el archivo raíz de la web con ese nombre si el directorio del cliente no ha especificado su propia copia. El navegador web aún debe señalar /clients/abc si el archivo existe allí o en la raíz. Del mismo modo, si hay una solicitud para news.html en el directorio del cliente y existe, entonces solo sirva ese archivo en lugar del news.html de la raíz web. La experiencia del usuario debe ser transparente.

Necesito que funcione para solicitudes en cualquier nombre de archivo. Si necesito, por ejemplo, agregar una nueva línea al .htaccess por cada archivo que pueda querer redireccionar, en lugar de ello frustra el propósito, ya que se necesita mucho mantenimiento y existe una buena probabilidad de errores debido a la gran cantidad de archivos.

En sus ejemplos, indique si su código se encuentra en el archivo .htaccess en el directorio del cliente o en la raíz web. Se prefiere la raíz web.

Respuesta

4

que parecía tener al menos un problema con cada uno de los ejemplos a bove. %{DOCUMENT_ROOT} parecía hacer lo incorrecto en ciertos lugares, y algunos caracteres / parecen faltar. Aquí está mi solución, que va en el .htaccess en la raíz web.

En lugar de usar dos reglas (una para el caso donde se encuentra el archivo bajo clientes/y una para no encontradas), todo lo que necesito verificar es si el archivo solicitado (o directorio) NO existe. Porque si existe, no se necesita ningún cambio, solo puede usar el archivo provisto en el directorio del cliente. Aquí está el código que decidí:

RewriteEngine on 
RewriteCond %{DOCUMENT_ROOT}/clients/$1/$2 !-f 
RewriteCond %{DOCUMENT_ROOT}/clients/$1/$2 !-d 
RewriteRule ^clients/([^/]+)/(.*)$ $2 [L] 

¡Gracias por su ayuda!

3
RewriteCond %{REQUEST_FILENAME} !-f 
+1

Parece demasiado corto para hacer lo que quiero. ¿Puedes explicar la lógica un poco? ¡Gracias! – DivideByHero

23
# If requested resource exists as a file or directory, skip next two rules 
RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR] 
RewriteCond %{DOCUMENT_ROOT}/$1 -d 
RewriteRule (.*) - [S=2] 
# 
# Requested resource does not exist, do rewrite if it exists in /archive 
RewriteCond %{DOCUMENT_ROOT}/archive/$1 -f [OR] 
RewriteCond %{DOCUMENT_ROOT}/archive/$1 -d 
RewriteRule (.*) /archive/$1 [L] 
# 
# Else rewrite requests for non-existent resources to /index.php 
RewriteRule (.*) /index.php?q=$1 [L] 

De Rewrite if files do not exist

0

Prueba esto:

RewriteEngine on 
RewriteRule ^clients/abc/ - [L] 
RewriteCond %{DOCUMENT_ROOT}clients/abc/$0 -f 
RewriteRule .* clients/abc/$0 [L] 
+0

¿Está destinado para .htaccess en la raíz web? – DivideByHero

+0

Sí, está destinado para el archivo .htaccess en el directorio raíz del documento. – Gumbo

0

Creo que quieres algo en este sentido:

RewriteEngine on 
RewriteCond %{DOCUMENT_ROOT}clients/$1/$2 -f 
RewriteRule ^clients/([^/]+)/(.*)$ %{DOCUMENT_ROOT}clients/$1/$2 [L] 
RewriteRule ^clients/([^/]+)/(.*)$ %{DOCUMENT_ROOT}$2 [L] 
+0

Buen punto. Pero en .Archivos htaccess El patrón no debe comenzar con una barra inclinada. Y sería más conveniente si usa la variable DOCUMENT_ROOT. – Gumbo

+0

¿Puedes aclarar cómo se debe actualizar esto con DOCUMENT_ROOT? No funciona como es. – DivideByHero

+0

Reemplazar en RewriteCond "/ home/blah/www /" por "% {DOCUMENT_ROOT}" y eliminarlo en las sustituciones. Elimine también el "/" inicial en los patrones de expresiones regulares. Entonces debería funcionar. – Gumbo

9

¿Qué tal esto?

# If requested resource exists as a file or directory go to it 
RewriteCond %{REQUEST_FILENAME} -f [OR] 
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule (.*) - [L] 

# Else rewrite requests for non-existent resources to /index.php 
RewriteRule (.*) /index.php?q=$1 [L] 
Cuestiones relacionadas