Estoy escribiendo un marco MVC-ish simple basado en PHP. Quiero que este marco pueda instalarse en cualquier directorio.
Mi script PHP toma la uri de solicitud y la divide en segmentos. Hace que el segmento 1 sea el controlador y el segmento 2 la acción. Todo va bien cuando hago esto:
http://www.example.com/mvc/module/test/
Irá al controlador y método del módulo específico. Ahora tengo un controlador predeterminado, el controlador de inicio, que está en la carpeta de inicio.
Ahora, cuando accedo a esta carpeta directamente http://www.example.com/mvc/home/ Mostrará un 403 prohibido, porque esta carpeta existe, en su lugar también debería volver a http://www.example.com /mvc/index.php
Si hubiera instalado el marco en una carpeta diferente, digamos que el marco de la carpeta tiene que redirigir de nuevo a http://www.example.com/framework/index.php
Me gustaría redirigir cada carpeta y archivo php de nuevo al index.php, dejando todo lo demás como está.
Mi primer problema que encontré fue que nunca se redirige a la carpeta correcta, siempre a la carpeta raíz del dominio.
Esto es lo que probé:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
index.php
o desea redirigir cada solicitud realizada a esa carpeta específicaindex.php
?Respuestas:
Su regla de reescritura se ve casi bien.
Primero asegúrese de que su
.htaccess
archivo esté en la raíz del documento (el mismo lugar queindex.php
) o solo afectará la subcarpeta en la que se encuentra (y cualquier subcarpeta dentro de eso, de forma recursiva).A continuación, realice un ligero cambio en su regla para que se vea algo así como:
En el momento en que solo coincida en
.
cuál es una instancia de cualquier personaje, necesita al menos.*
hacer coincidir cualquier número de instancias de cualquier personaje.La
$_GET['path']
variable contendrá la estructura de directorio falsa,/mvc/module/test
por ejemplo, que luego puede usar en index.php para determinar el Controlador y las acciones que desea realizar.Si desea que todo el asunto se instala en un subdirectorio, como por ejemplo
/mvc/
, o/framework/
la forma menos complicada de hacerlo es cambiar la regla de reescritura ligeramente para tener en cuenta.Y asegúrese de que
index.php
está en esa carpeta mientras el.htaccess
archivo está en la raíz del documento.Alternativa a
$_GET['path']
(actualizado febrero '18 y enero '19)En realidad no es necesario (ni siquiera común ahora) establecer la ruta como una
$_GET
variable, muchos marcos dependerán$_SERVER['REQUEST_URI']
para recuperar la misma información, normalmente para determinar qué controlador usar, pero el principio es exactamente el mismo.Esto simplifica el
RewriteRule
ligeramente a medida que no es necesario para crear la ruta de parámetros (que significa original de la OPRewriteRule
hará ahora el trabajo):Sin embargo , la regla sobre la instalación en un subdirectorio todavía se aplica, p. Ej.
Las banderas:
NC
= Sin mayúsculas y minúsculas (no distingue entre mayúsculas y minúsculas, no es realmente necesario ya que no hay caracteres en el patrón)L
= Último (dejará de reescribirse después de esta Reescritura, así que asegúrese de que sea lo último en su lista de reescrituras)QSA
= Cadena de consulta Anexar, en caso de que tenga algo como?like=penguins
en el extremo que desea mantener y pasar a index.php.fuente
Options +Indexes
y index.php incluido enDirectoryIndex
le podría dejar fuera de index.php por completo y sólo usar/?path=$1
Esto es cierto cuando haciendo reescribe a través de .htaccess en lugar de en una<Directory>
directiva de tipo httpd-vhosts.conf .$_GET['path']
si agregapath=whatever
a la URL.$_GET
así que habría requerido(.*)
... es divertido, pero la RewriteRule que el OP estaba usando hace 6 años no funcionó para ellos entonces, pero con la forma en que la arquitectura MVC tiene evolucionó con PHP (como puse en el bit actualizado del 18 de febrero ) ahora ... supongo que se adelantaron a su tiempo :) Todavía necesita la ruta correcta al/mvc/
directorio, por supuesto.Para redirigir todo lo que no existe
index.php
, también puede usar laFallBackResource
directivaFunciona igual que
ErrorDocument
, cuando solicita una ruta o archivo inexistente en el servidor, la directiva silenciosamente reenvía la solicitud aindex.php
.Si desea redirigir todo (
including existant files or folders
) aindex.php
, puede usar algo como lo siguiente:Tenga en cuenta que el patrón
^((?!index\.php).+)$
coincide con cualquier uri, exceptoindex.php
que hemos excluido la ruta de destino para evitar un error de bucle infinito.fuente
DirectoryIndex index.php
*
lugar de+
en el patrón si también desea redirigir la ruta raíz.Puedes usar algo como esto:
Esto redirigirá cada consulta al index.php del directorio raíz. Tenga en cuenta que también redirigirá las consultas para los archivos que existen, como imágenes, archivos javascript o hojas de estilo.
fuente
Hay un "truco" para este problema que se adapta a todos los escenarios, una solución tan obvia que tendrá que probarlo para creer que realmente funciona ... :)
Aquí está...
Básicamente, le está pidiendo a MOD_REWRITE que reenvíe
index.php
la solicitud de URI siempre que exista un archivo ¡ Y siempre que el archivo solicitado no exista !Al investigar el código fuente de MOD-REWRITE para comprender cómo funciona, me di cuenta de que todas sus comprobaciones siempre ocurren después de la verificación si el archivo al que se hace referencia existe o no. Solo entonces
RegEx
se procesan. Incluso cuando su URI apunta a una carpeta, Apache aplicará la verificación de los archivos de índice que figuran en su archivo de configuración.Basado en ese simple descubrimiento, resultó obvio que una validación de archivo simple sería suficiente para todas las llamadas posibles , siempre que toquemos dos veces la verificación de presencia del archivo y enrutemos ambos resultados al mismo punto final, cubriendo el 100% de las posibilidades.
IMPORTANTE: Observe que no hay " / " en
index.php
. Por defecto, MOD_REWRITE usará la carpeta que está configurada como "carpeta base" para el reenvío. Lo bueno de esto es que no necesariamente tiene que ser la "carpeta raíz" del sitio, lo que permite que esta solución funcione paralocalhost/
cualquier subcarpeta que la aplique.En última instancia, algunas otras soluciones que probé antes (las que parecían estar funcionando bien) rompieron la capacidad de PHP de "requerir" un archivo a través de su ruta relativa, que es un fastidio. Ten cuidado.
Algunas personas pueden decir que esta es una solución poco elegante. Puede ser, en realidad, pero en lo que respecta a las pruebas, en varios escenarios, varios servidores, varias versiones diferentes de Apache, etc., ¡esta solución funcionó al 100% en todos los casos!
fuente
FallbackResource index.php
línea funcionaba en una Mac (OS X 10.11) pero no funcionaba bajo Centos 7.5. Sin embargo: estoRewriteRule
también reescribe la ubicación de los archivos CSS, por ejemplo. Como necesitaba redirigir solo archivos PHP, modifiqué la reglaRewriteRule ^(.*)php$ index.php [L,QSA]
. YMMV.RewriteRule ^(.*)\.php$ index.php [L,NE,QSA]
(que no necesita condiciones para funcionar). Hoy en día, sin embargo, uso una regla más económica:RewriteRule ^.+$ index.php [L,NE,QSA]
que se puede combinar con las condicionesRewriteCond %{REQUEST_FILENAME} !-f
yRewriteCond %{REQUEST_FILENAME} !-d
, o incluso conRewriteCond $1 !^(index\.php|assets|robots\.txt|favicon\.ico)
ser realmente específico.Respuesta tonta, pero si no puede entender por qué no está redirigiendo, verifique que lo siguiente esté habilitado para la carpeta web.
AllowOverride All
¡Esto le permitirá ejecutar htaccess que debe estar ejecutándose! (existen alternativas pero no activadas causarán problemas https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride )
fuente
Después de hacerlo, no olvide cambiar su etiqueta de anclaje, inicio
Ejemplo:
fuente
en caso de que aún se pregunte cómo redirigir todas las solicitudes, ya sea si el directorio existe (para las carpetas y los archivos del marco central) al controlador del índice del marco, después de algunos intentos de error / éxito, noté que solo necesitaba cambiar el RewriteCond en el .htaccess expediente
la condición anterior indica "archivos no encontrados" y "directorios no encontrados", ok, ¿qué pasa si simplemente elimina la línea "no encontrado" (! -d) y termina con algo como lo siguiente:
Funcionó para mí como un encanto
fuente