Как я могу отладить правила mod_rewrite?
Это случай "задать вопрос и ответить на него сам", который я публикую для всех, у кого такая же проблема.
У меня были некоторые проблемы при отладке набора правил mod_rewrite в файле.htaccess на общем сервере, где я даже не мог получить доступ к журналам ошибок Apache. Я нашел изящный способ их отладки, а именно:
Напишите короткий скрипт, который просто распечатывает переменные строки запроса. например, в PHP:
<?='<pre>',htmlentities(print_r($_GET,true)),'</pre>'?>
это все, что тебе нужно.
Допустим, вы назвали этот скрипт "show.php" и поместили его в / public_html. Затем в файле.htaccess определите точку в вашем наборе правил, которая, по вашему мнению, может вызывать проблему, и вставьте это правило:
RewriteRule (.*) /show.php?url=$1 [END]
Эффект такой же, как при вставке оператора PRINT в обычную программу. Он сообщит вам, что (а) вы достигли этой точки в наборе правил и (б) каков текущий перезаписанный URL.
Это не так flash, как настоящий инструмент отладки, но он выполняет свою работу.
Если вы используете Apache <2.3.9, вам придется использовать [L]
вместо [END]
, В этом случае следует обратить внимание на то, что ваш набор правил не должен пытаться переписать "/show.php" на что-либо еще. Если это проблема, вы можете это исправить, добавив это правило в самом верху:
RewriteRule ^show.php$ - [L]
... Просто не забудьте удалить его, когда закончите отладку!
2 ответа
Очень полезное понимание. В течение многих лет я пытался выяснить, как отлаживать правила mod_rewrite без необходимости иметь root-доступ и помещать правила в httpd.conf. Это делает это!
У вас есть одна незначительная ошибка в вашем PHP:
<?='<pre>',htmlentities(print_r($_GET),true),'</pre>'?>
В этом коде print_r() выводит все в $_GET в stdout, а затем возвращает значение true, которое htmlentities() выбирает в качестве первого аргумента. htmlentities() также получает литерал true в качестве второго аргумента, который является необязательным аргументом, который сообщает htmlentities(), следует ли связываться с одинарными и / или двойными кавычками.
Я думаю, что вы хотели:
<?='<pre>',htmlentities(print_r($_GET, true)),'</pre>'?>
Это говорит print_r() отформатировать все в $_GET. Передача true в качестве второго аргумента для print_r() говорит ему не выводить результат в stdout, а вместо этого помещать результат в строку и возвращать эту строку в качестве возвращаемого значения print_r(). Затем htmlentities() получает эту строку в качестве одного входного параметра и выполняет соответствующие замены, чтобы заставить браузер отображать строку как есть, а не позволять браузеру интерпретировать строку. EG -
<i>text</i>
будет переведен на:
<i>text</i>
что заставит браузер отображать:
<i>text</i>
вместо отображения слова "текст" курсивом:
текст