Как я могу отладить правила mod_rewrite?

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

У меня были некоторые проблемы при отладке набора правил mod_rewrite в файле.htaccess на общем сервере, где я даже не мог получить доступ к журналам ошибок Apache. Я нашел изящный способ их отладки, а именно:

  1. Напишите короткий скрипт, который просто распечатывает переменные строки запроса. например, в PHP:

    <?='<pre>',htmlentities(print_r($_GET,true)),'</pre>'?>
    

    это все, что тебе нужно.

  2. Допустим, вы назвали этот скрипт "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>

будет переведен на:

&lt;i&gt;text&lt;/i&gt;

что заставит браузер отображать:

<i>text</i>

вместо отображения слова "текст" курсивом:

текст

Другая возможность:

используйте этот онлайн тестер htaccess:

http://htaccess.madewithlove.be/

Другие вопросы по тегам