Перенаправить все в index.php htaccess

Мои извинения за 10000000-й вопрос по этой теме, но я просто не могу заставить его работать так, как я этого хочу.

Я пишу простой php mvc'ish framework. Я хочу, чтобы эта среда могла быть установлена ​​в любом каталоге.

Что мой PHP скрипт делает: Захватывает запрос uri и разбивает его на сегменты. Создание сегмента 1 контроллера и сегмента 2 действия. Это нормально, когда я это делаю:

http://www.domain.com/mvc/module/test/

Он перейдет к конкретному модулю контроллера и методу. Теперь у меня есть контроллер по умолчанию, домашний контроллер, который находится в папке дома.

Теперь, когда я присоединяюсь к этой папке напрямую http://www.domain.com/mvc/home/ Он будет отображать 403 запрещенных, потому что эта папка существует, вместо этого она также должна вернуться к http://www.domain.com/mvc/index.php

Если бы я установил фреймворк в другой папке, скажем, что для рамки фреймов он должен перенаправить обратно на http://www.domain.com/framework/index.php

Я хотел бы перенаправить каждую папку и файл php обратно в index.php, оставив все остальное так, как есть.

Моя первая проблема, с которой я столкнулся, никогда не перенаправлялась в нужную папку, всегда в корневую папку домена.

Это то, что я пробовал:

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

Я действительно надеюсь, что кто-то может помочь мне или указать мне в правильном направлении!

Спасибо, много!

Ответ 1

Ваше правило переписывания выглядит почти нормально.

Сначала убедитесь, что ваш файл .htaccess находится в корневом каталоге вашего документа (в том же месте, что и index.php), или он будет влиять только на подпапку, в которой он находится (и любые подпапки в нем - рекурсивно).

Затем внесите небольшое изменение в ваше правило, чтобы оно выглядело примерно так:

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

На данный момент вы просто совпадаете . который является одним экземпляром любого символа, вам нужно по крайней мере .* чтобы соответствовать любое количество экземпляров любого символа.

Переменная $_GET['path'] будет содержать поддельную структуру каталогов, например /mvc/module/test, которую вы можете затем использовать в index.php для определения контроллера и действий, которые вы хотите выполнить.


Если вы хотите, чтобы весь shebang был установлен в подкаталог, такой как /mvc/ или /framework/ то наименее сложный способ сделать это - слегка изменить правило перезаписи, чтобы учесть это.

RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]

И убедитесь, что ваш index.php находится в этой папке, а файл .htaccess находится в корне документа.


Альтернатива $_GET['path'] (обновлено в феврале '18 и январе '19)

На самом деле нет необходимости (и даже сейчас не принято) устанавливать путь как переменную $_GET, многие фреймворки будут полагаться на $_SERVER['REQUEST_URI'] для получения той же информации - обычно для определения того, какой контроллер использовать, - но принцип таков: точно так же.

Это немного упрощает RewriteRule как вам не нужно создавать параметр пути (что означает, что теперь оригинальная RewriteRule OP будет работать):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

Тем не менее, правило об установке в подкаталог все еще применяется, например,

RewriteRule ^.*$ /mvc/index.php [L,QSA]



Флаги:

NC= Нет регистра (не чувствительно к регистру, на самом деле не нужно, поскольку в шаблоне нет символов)

L= Последний (после перезаписи он перестанет перезаписываться, поэтому убедитесь, что он является последним в вашем списке перезаписей)

QSA= Query String Apend, на тот случай, если у вас есть что-то вроде ?like=penguins на конце, который вы хотите сохранить и передать в index.php.

Ответ 2

Чтобы перенаправить все, что не существует на index.php, вы также можете использовать директиву FallBackResource

FallbackResource /index.php

Он работает так же, как и ErrorDocument, когда вы запрашиваете несуществующий путь или файл на сервере, директива молча запрашивает запрос index.php.

Если вы хотите перенаправить все (including existant files or folders) на index.php, вы можете использовать что-то вроде следующего:

RewriteEngine on

RewriteRule ^((?!index\.php).+)$ /index.php [L]

Обратите внимание, что шаблон ^((?!index\.php).+)$ соответствует любому uri, кроме index.php, мы исключили путь назначения, чтобы предотвратить ошибку с бесконечным циклом.

Ответ 3

Вы можете использовать что-то вроде этого:

RewriteEngine on
RewriteRule ^.+$ /index.php [L]

Это перенаправляет каждый запрос в корневой каталог index.php. Обратите внимание, что он также перенаправляет запросы на существующие файлы, такие как изображения, файлы javascript или таблицы стилей.

Ответ 4

Существует одна "трюк" для этой проблемы, которая подходит ко всем сценариям, настолько очевидное решение, что вам придется попробовать, чтобы он верил, что на самом деле это работает...:)

Вот он...

<IfModule mod_rewrite.c>

   RewriteEngine On

   RewriteCond %{REQUEST_FILENAME}  -f [OR]
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ index.php [L,QSA]

</IfModule>

В принципе, вы просите MOD_REWRITE пересылать index.php запрос URI всегда, когда файл существует И всегда, когда запрошенный файл не существует

При изучении исходного кода MOD-REWRITE, чтобы понять, как он работает, я понял, что все его проверки всегда происходят после проверки, существует ли файл с ссылками. Только тогда обрабатываются RegEx. Даже когда ваш URI указывает на папку, Apache будет принудительно проверять файлы индекса, указанные в его файле конфигурации.

Основываясь на этом простом открытии, оказалось очевидным, что для всех возможных вызовов будет достаточно простой проверки файлов, поскольку мы дважды используем проверку наличия файла и маршрутизируем оба результата на один и тот же конец, точка, покрывающая 100% возможностей.

ВАЖНО: Обратите внимание, что в index.php нет "/". По умолчанию MOD_REWRITE будет использовать папку, в которой она установлена ​​как "базовая папка" для пересылки. Красота заключается в том, что необязательно быть "корневой папкой" сайта, позволяя этому решению работать для localhost/ и/или любой вложенной папки, к которой вы его примените.

В конечном счете, некоторые другие решения, которые я тестировал ранее (те, которые, казалось, работали нормально), нарушили способность PHP "требовать" файл через его относительный путь, который является обломком. Будьте осторожны.

Некоторые люди могут сказать, что это неэлегантное решение. Это может быть, на самом деле, но, что касается тестов, в нескольких сценариях, нескольких серверах, нескольких версиях Apache и т.д., Это решение работало на 100% во всех случаях!

Ответ 5

Глупый ответ, но если вы не можете понять, почему его не перенаправлять, проверьте, что для веб-папки включено следующее.

AllowOverride All

Это позволит вам запустить htaccess, который должен быть запущен! (есть альтернативы, но не на вызове проблемы https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)