Переадресация всех запросов в один файл index.php для несуществующих файлов, но * включая * сам индекс.php
Итак, у меня есть довольно типичная конфигурация "единой точки входа" в файле.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
И это прекрасно работает. Теперь - я тоже какое то поведение по запросу к самому файлу index.php. Итак, я делаю это:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
#file must not exist:
RewriteCond %{REQUEST_FILENAME} !-f [or]
# *unless* this is the index.php *itself*, then I also
#want to pass it to itself.
RewriteCond %{REQUEST_FILENAME} index.php
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Таким образом, у нас есть своего рода исключение - продолжать, когда файл не существует, но также и когда он существует, но это "index.php".
И это работает, но, к сожалению, это также работает для файлов глубже в структуре. То, что я хочу, это поймать только то, что "index.php" находится на том же уровне, что и сам.htaccess.
Обновление: Может быть, я должен уточнить. Я хочу создать очень общую, единую точку входа для php, например:
https://github.com/kpion/point1
Это "работает", но я чувствую, что должен сделать это немного по-другому. Я уже задавал подобный вопрос ( отличный способ заставить единую точку входа (фронт-контроллер) работать с наиболее распространенными настройками веб-сервера), но он был расценен как "слишком длинный", так что это мой второй подход:)
Пожалуйста, имейте в виду, что я не могу использовать ^ / index.php - в условии, потому что запрос 'uri действительно не должен начинаться с него. Этот htaccess также может быть глубже, то есть глубже в корне документа. На самом деле это довольно часто, когда у меня много небольших проектов в / var / www / html, и я не хочу создавать vhost для всего. Итак, "корень" - это / var / www / html, а теперь:
Пример:
Проект находится в /var/www/html/point/point1
.Htaccess находится внутри него. Он перенаправляет все запросы к несуществующим файлам в index.php. С моими несколькими дополнительными строками он также перенаправляет себя в index.php.
Примечание: %{REQUEST_URI} в этом случае, когда мы открываем /var/www/html/point/point1, равно "/point/point1/index.php"
Это не /index.php
Это работает нормально, когда я вызываю http://localhost/point/point1/.local/noExistinFile или http://localhost:82/point/point1/ (это будет указывать на index.php, которому будет соответствовать мой последний RewriteCond).
Но когда у меня есть файл, расположенный в /var/www/html/point/point1/.local/index.php, и я звоню http://localhost2/point/point1/.local/index.php - я не хочу, чтобы это прошло условия, и я не хочу, чтобы это было перенаправлено в index.php.
Поэтому мне нужно что-то относительно местоположения.htaccess.
2 ответа
Ах, я забыл, я задал этот вопрос. Для всех интересующихся: я выяснил, решение довольно простое:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
# lets forward the index.php itself as well, to be later consistent in how we handle things:
RewriteRule ^(index.php)$ index.php?url=index.php [QSA,L]
Последняя строка делает работу, потому что:
Приведенный выше RewriteCond, очевидно, не применяется (по умолчанию они работают только для "RewriteRule" непосредственно ниже). Так что -f (не должен существовать) не применяется, что круто.
Теперь ключевая часть: проверенная строка в RewriteRule - это файл / dir относительно каталога, в котором находится.htaccess. Итак, если файл.htaccess находится внутри /var/www/html/point/point1, и мы запрашиваем:
http://whateverhostwesetpointingtothisdir/index.php, тогда строка, проверяемая в RewriteRule, является в точности "index.php". И когда мы просим
Затем http://localhost/point/point1/blah/index.php, если предположить, что... point1 указывает на наш каталог 'point1', то что проверяется, так это "blah/index.php".
Вот почему RewriteRule ^(index.php)$ соответствует файлу 'index.php', который находится в том же каталоге, что и сам.htaccess. Независимо от имени хоста, или имени родительского каталога, или чего-либо еще.
Кстати: если мы запрашиваем http://whateverhostwesetpointingtothisdir/, то это будет работать также, если мы установили DirectoryIndex index.php, но это на самом деле не связано.
Это должно работать:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
#file must not exist:
RewriteCond %{REQUEST_FILENAME} !-f [or]
#or is /index.php
RewriteCond %{REQUEST_URI} ^/index.php$
RewriteRule ^(.*)$ index.php?url=$1 [NC,L,QSA]