Я пишу простой MVC-фреймворк на основе PHP. Я хочу, чтобы этот фреймворк можно было установить в любой каталог.
Мой PHP-скрипт захватывает URI запроса и разбивает его на сегменты. Он делает сегмент 1 контроллером, а сегмент 2 действием. Все идет нормально, когда я делаю это:
http://www.example.com/mvc/module/test/
Он перейдет к конкретному контроллеру модуля и методу. Теперь у меня есть контроллер по умолчанию, домашний контроллер, который находится в домашней папке.
Теперь, когда я напрямую обращаюсь к этой папке http://www.example.com/mvc/home/, будет отображаться 403 запрещено, потому что эта папка существует, вместо этого она также должна вернуться на http://www.example.com /mvc/index.php
Если бы я установил фреймворк в другую папку, скажем, фреймворк папки, он должен перенаправить обратно на http://www.example.com/framework/index.php
Я хотел бы перенаправить каждую папку и файл php обратно в index.php, оставив все остальное как есть.
Моя первая проблема, с которой я столкнулся, заключалась в том, что он никогда не перенаправляется в нужную папку, всегда в корневую папку домена.
Вот что я пробовал:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
index.php
или вы хотите перенаправить каждый запрос, сделанный в эту конкретную папкуindex.php
?Ответы:
Ваше правило перезаписи выглядит почти нормально.
Сначала убедитесь, что ваш
.htaccess
файл находится в корне вашего документа (в том же месте, что иindex.php
), иначе он повлияет только на подпапку, в которой он находится (и любые подпапки в ней - рекурсивно).Затем внесите небольшое изменение в свое правило, чтобы оно выглядело примерно так:
На данный момент вы просто сопрягая на
.
который один экземпляр любого характера, необходимо , по крайней мере ,.*
чтобы соответствовать любому количеству экземпляров любого характера.$_GET['path']
Переменный будет содержать структуру каталогов подделки, так/mvc/module/test
, например, которые затем можно использовать в index.php для определения контроллера и действий , которые необходимо выполнить.Если вы хотите, чтобы весь shebang был установлен в подкаталоге, например,
/mvc/
или/framework/
наименее сложный способ сделать это, это немного изменить правило перезаписи, чтобы принять это во внимание.И убедитесь, что вы
index.php
находитесь в этой папке, пока.htaccess
файл находится в корне документа.Альтернатива
$_GET['path']
(обновлено февраль 18 и январь 19)На самом деле нет необходимости (и даже сейчас) устанавливать путь как
$_GET
переменную, многие фреймворки будут полагаться на$_SERVER['REQUEST_URI']
получение одной и той же информации - обычно для определения того, какой контроллер использовать, - но принцип тот же.Это
RewriteRule
немного упрощает, так как вам не нужно создавать параметр пути (что означает, что оригинал OP теперьRewriteRule
будет работать):Однако правило установки в подкаталоге по-прежнему применяется, например
Флаги:
NC
= Без регистра (регистр не учитывается, в действительности нет необходимости, поскольку в шаблоне нет символов)L
= Последний (он перестанет перезаписывать после этой перезаписи, поэтому убедитесь, что это последняя вещь в вашем списке перезаписей)QSA
= Строка запроса Добавить, на случай, если у вас есть что-то вроде?like=penguins
того, что вы хотите сохранить и передать в index.php.источник
Options +Indexes
и index.php включены вDirectoryIndex
вы могли бы уйти от index.php в целом и просто использовать/?path=$1
Это справедливо , когда выполнение перезаписи через .htaccess, а не в<Directory>
директиве типа httpd-vhosts.conf .$_GET['path']
если добавитpath=whatever
к URL.$_GET
поэтому это потребовалось(.*)
... это забавно, но RewriteRule, который OP использовал 6 лет назад, тогда для них не работал - но с тем, как архитектура MVC эволюционировал с помощью PHP (как я добавил в обновленной версии от 18 февраля ), теперь это будет ... думаю, они опередили свое время :)/mvc/
Конечно, по- прежнему нужен правильный путь к каталогу.Чтобы перенаправить все, что не существует
index.php
, вы также можете использоватьFallBackResource
директивуОн работает так же, как
ErrorDocument
если вы запрашиваете несуществующий путь или файл на сервере, директива молча пересылает запрос наindex.php
.Если вы хотите перенаправить все (
including existant files or folders
) наindex.php
, вы можете использовать что-то вроде следующего:Обратите внимание, что шаблон
^((?!index\.php).+)$
соответствует любому uri, за исключением того, чтоindex.php
мы исключили путь назначения, чтобы предотвратить ошибку бесконечного цикла.источник
DirectoryIndex index.php
*
вместо+
в шаблоне, если вы также хотите перенаправить сам корневой путь.Вы можете использовать что-то вроде этого:
Это перенаправит каждый запрос на index.php корневого каталога. Обратите внимание, что он также будет перенаправлять запросы для существующих файлов, таких как изображения, файлы javascript или таблицы стилей.
источник
Есть один «трюк» для этой проблемы, который подходит для всех сценариев, настолько очевидное решение, что вам придется попробовать его, чтобы поверить, что оно действительно работает ... :)
Вот...
По сути, вы просите MOD_REWRITE перенаправлять
index.php
запрос URI всегда, когда файл существует, И всегда, когда запрошенный файл не существует !Изучая исходный код MOD-REWRITE, чтобы понять, как он работает, я понял, что все его проверки всегда происходят после проверки, существует ли указанный файл или нет. Только после этого
RegEx
они обрабатываются. Даже когда ваш URI указывает на папку, Apache будет принудительно проверять файлы индекса, перечисленные в его файле конфигурации.Основываясь на этом простом открытии, стало очевидным, что простой проверки файла будет достаточно для всех возможных вызовов , поскольку мы дважды коснемся проверки наличия файла и направим оба результата в одну и ту же конечную точку, покрывая 100% возможностей.
ВАЖНО: Обратите внимание, что в скобках нет символа " / "
index.php
. По умолчанию MOD_REWRITE будет использовать папку, которую он установлен в качестве «базовой папки» для пересылки. Его прелесть в том, что это не обязательно должна быть «корневая папка» сайта, что позволяет этому решению работать наlocalhost/
и / или любой вложенной папки, в которой вы его применяете.В конечном счете, некоторые другие решения, которые я тестировал ранее (те, которые, казалось, работали нормально), нарушили способность PHP «запрашивать» файл по его относительному пути, что является обломом. Быть осторожен.
Некоторые могут сказать, что это неэлегантное решение. Может быть, действительно, но что касается тестов, в нескольких сценариях, нескольких серверах, нескольких разных версиях Apache и т.д., это решение работало на 100% во всех случаях!
источник
FallbackResource index.php
линия работала на Mac (OS X 10.11), но не работала под Centos 7.5. Однако: например, этоRewriteRule
также переписывает расположение файлов CSS. Поскольку мне нужно было перенаправлять только файлы PHP, я изменил правило наRewriteRule ^(.*)php$ index.php [L,QSA]
. YMMV.RewriteRule ^(.*)\.php$ index.php [L,NE,QSA]
(для работы не требуются условия). В настоящее время, однако, я использую более недорогое правило:RewriteRule ^.+$ index.php [L,NE,QSA]
которое может сочетаться с условиямиRewriteCond %{REQUEST_FILENAME} !-f
иRewriteCond %{REQUEST_FILENAME} !-d
, или даже,RewriteCond $1 !^(index\.php|assets|robots\.txt|favicon\.ico)
чтобы быть действительно конкретным.Глупый ответ, но если вы не можете понять, почему он не перенаправляет, проверьте, что для веб-папки включено следующее:
AllowOverride All
Это позволит вам запустить htaccess, который должен быть запущен! (есть альтернативы, но они не вызовут проблемы https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride )
источник
Сделав это, не забудьте изменить свой тег привязки, домой
Пример:
источник
на всякий случай вам все еще было интересно, как перенаправить весь запрос, если каталог существует (для основных папок и файлов структуры), в обработчик индекса инфраструктуры, после некоторых попыток ошибки / успеха я просто заметил, что мне просто нужно было изменить RewriteCond в .htaccess файл
в приведенном выше условии указано «не найденные файлы» и «не найденные каталоги», хорошо, а что, если просто удалить строку «не найден» (! -d) и закончиться чем-то вроде следующего:
Это сработало для меня как шарм
источник