¿Cómo hacer reglas de reescritura relativas al archivo .htaccess?

¿Cómo hacer reglas de reescritura relativas al archivo .htaccess?

Actualmente tengo un archivo .htaccess como este.

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} ^/(always|rewrite|these|dirs)/ [NC]

RewriteRule ^(.*)$ router.php [L,QSA]

Funciona cuando los archivos del sitio están en document_root del servidor web (es decir, domain.com/abc.php-> <DOCUMENT_ROOT>/abc.php). Pero en nuestra configuración actual (que no se puede modificar), esto no está garantizado. A veces podemos tener una carpeta arbitraria entre la raíz del documento y la carpeta del archivo .htaccess (es decir, domain.com/something/abc.php-> <DOCUMENT_ROOT>/something/abc.php). El único problema es que el segundo RewriteCondya no funciona. ¿Existe alguna forma de verificar dinámicamente si la ruta a la que se accede es una ruta relativa al .htaccessarchivo?

Por ejemplo:

Si tengo un sitio donde domain.com/prefix/está el directorio del .htaccessarchivo.

NOT FORCED TO REWRITE -> domain.com/prefix/index.php
FORCED TO REWRITE -> domain.com/prefix/rewrite/index.php

Si tengo un sitio donde domain.com/está el directorio del .htaccessarchivo.

NOT FORCED TO REWRITE -> domain.com/index.php
FORCED TO REWRITE -> domain.com/rewrite/index.php

Respuesta1

Hay una solución pero no es sencilla.

Usar RewriteMap.

Así es como lo haría:

Crear unReescribir mapaarchivo. Veraquí para más información. Este es un archivo de texto muy simple con: primero, la URL incorrectasin el '/', entoncesun espacio(al menos) y luego la URL correcta, así:

ok​ /folder1/
ok /folder2/
ok /folder3/

Entonces el código:

RewriteMap myfoldermap \
  dbm:/web/htdocs/yourwebsite.com/rewriterules/myfoldermap.map

RewriteCond %{REQUEST_URI} ^/([^/]+)/(.*)
# Now in '%1' there's the name of the folder
# Don't touch the URL but...
# ...check if it exists in the map file
RewriteRule (.*) - [QSA,E=FOLDERMAP:${myfoldermap:%1|notfound}]

# if the environment is neither empty or not found...
RewriteCond %{E:FOLDERMAP} !^(notfound|)$
# this means we found something...
# => apply the RewriteRule
RewriteRule ^(.*)$ router.php [L,QSA]

Si no funciona: lea mis "dos consejos" habituales y agregue el registro de reescritura en su pregunta.

Dos pistas:

Si no está en un entorno alojado (= si es su propio servidor y puede modificar los hosts virtuales, no solo los .htaccessarchivos), intente utilizar la RewriteLogdirectiva: le ayudará a localizar estos problemas:

# Trace:
# (!) file gets big quickly, remove in prod environments:
RewriteLog "/web/logs/mywebsite.rewrite.log"
RewriteLogLevel 9
RewriteEngine On

Mi herramienta favorita para comprobar la expresión regular:

http://www.quanetic.com/Regex(¡No olvide elegir ereg(POSIX) en lugar de preg(PCRE)!)

Respuesta2

HaceObligado a reescribir¿Significa que la regla de reescritura debería funcionar incluso si el archivo o directorio solicitado existe?

En caso afirmativo, intente evitar crear el archivo/directorio.

O sepárelo en dos reglas:

RewriteRule ^/(siempre|reescribir|estos|directorios)/ router.php [L]

ReescribirCond %{REQUEST_FILENAME} !-f

ReescribirCond %{REQUEST_FILENAME} !-d

Reescribir regla ^(.*)$ router.php [L,QSA]

Respuesta3

Si te entiendo correctamente (particularmente no sé a qué te refieres conobligado a reescribir),RewriteBasees para ti.

POR CIERTO:no uses cosas comodominio.com:-)

información relacionada