Принудительное удаление index.php с помощью .htaccess - PullRequest
0 голосов
/ 08 июня 2011

В настоящее время я использую следующее, чтобы переписать http://www.site.com/index.php/test/, чтобы также работать напрямую с http://www.site.com/test/, но я хотел бы не только разрешить вторую версию, но я также хотел бы ПРИНЯТЬ вторую версию. Если пользователь переходит на http://www.site.com/index.php/test/, он должен немедленно перенаправить его на http://www.site.com/test/. index.php никогда не должен появляться в URL. Оговорка: это относится только к первому index.php. Если у меня есть заголовок типа http://www.site.com/index.php/2011/06/08/remove-index.php-from-urls/, он должен оставить второй index.php, так как он является частью URL.

Действующее правило, которое разрешает, но не заставляет: #Remove index.php RewriteCond $ 1! ^ (Index.php | images | css | js | robots.txt) RewriteRule ^ (. *) $ /Index.php/$1 [L]

Спасибо.

Ответы [ 2 ]

3 голосов
/ 08 июня 2011

Первый (и неправильный) ответ - см. Ниже

Вы можете выполнить перенаправление с помощью следующих директив (в следующем порядке):

RewriteCond %{REQUEST_URI} ^index.php
RewriteRule ^index\.php/(.+)$ /$1 [R,L]

RewriteCond $1 !^(index.php|images|css|js|robots.txt)
RewriteRule ^(.*?)$ /index.php/$1 [L]

Сначала перенаправит все запросы, начинающиеся с index.php, на соответствующий сокращенный URL-адрес, а затем тихо обработает index.php/etc со вторым правилом.

РЕДАКТИРОВАТЬ - Пожалуйста, продолжайте читать!

Фактически, решение выше генерирует бесконечный цикл перенаправления, потому что Apache выполняет следующие действия (скажем, мы запрашиваем /index.php/abc):

  1. первый RewriteCond совпадений
  2. Apache перенаправляет [R], то есть генерирует новый HTTP-запрос, к /abc
  3. /abc первый сбой RewriteCond
  4. /abc соответствует второму RewriteCond
  5. Apache не перенаправляет, а переписывает этот URI (поэтому он делает «скрытый» запрос) в /index.php/abc. Мы снова в точке 1, это цикл.

Обратите внимание ...

  • Используя флаг [L] (последнее правило), мы можем только сказать Apache не обрабатывать больше правил перезаписи, но только если текущее правило совпадает. Так как новый HTTP-запрос сделан, нет никакой информации о том, как перенаправление мы могли пройти через. Таким образом, в любое время одно из двух совпадений и в любом случае генерирует новый запрос (=> цикл)
  • Использование флага [C] (правила цепочки) бессмысленно, поскольку Apache обрабатывает правило только в том случае, если совпадает предыдущее правило, а два наших правила взаимно исключают.
  • Использование флага [NS] (not if subrequest) в правиле # 1 снова не вариант, поскольку он просто не применим к нашему случаю (см. Apache RewriteRule docs об этом)
  • Установка переменных env не является опцией (увы), так как новый запрос выполняется на pt 2, тем самым уничтожая все переменные среды, которые мы установили.

Альтернативным решением может быть, например, переписать. /abc, до /index.php?path=abc. Это делается по этим правилам (пожалуйста, удалите аналогичное правило RedirectMatch перед добавлением этих):

RedirectMatch ^/index\.php(/.*) $1

RewriteCond %{REQUEST_URI} !^/(index.php|images|css|js|robots.txt|favicon.ico)
RewriteRule ^(.+) /index.php?path=$1 [L,QSA]

Я не знаю внутренностей скриптов CodeIgniter, но, как и большинство скриптов MVC, он будет читать $_REQUEST['PATH_INFO'], чтобы понять, какая страница запрашивается. Вы можете немного изменить код, который распознает страницу следующим образом (я предположил, что путь к странице хранится в $page var):

$page = $_REQUEST['PATH_INFO'];
if(isset($_GET['path']) && strlen($_GET['path'])) $page = $_GET['path']; // Add this line

Это не сломает предыдущий код и не выполнит то, что вы просили.

2 голосов
/ 08 июня 2011

Как вы писали, если пользователь перейдет на http://www.site.com/index.php/test/, это правило немедленно перенаправит его на http://www.site.com/test/

RedirectMatch 301 /index.php/(.*)/$ /$1

Я не уверен, что это именно то, что вам нужно, поскольку ваше текущее правило переписывания противоположно моему.

...