2015-08-18 23 views
1

Я пытаюсь использовать .htaccess и mod_rewrite для перенаправления URL-адресов на моем сайте.Как перенаправить подкаталог в каталог и строку запроса?

Я хотел бы иметь его так, чтобы /questions/12345 и /users/12345 перенаправлять /questions/display.php?id=12345 и /users/display.php?id=12345 соответственно.

Я бы также хотел бы добавить ярлык, вроде Stack биржи, в результате чего /q/12345/6789 переписывается /questions/display.php?id=12345&refer=6789.

До сих пор, полистав severalsources, я получил это:

RewriteEngine On 
RewriteRule ^users/([^/]+) /users/display.php?id=$1 [NC] 
RewriteRule ^questions/([^/]+) /questions/display.php?id=$1 [NC] 
RewriteRule ^q/([^/]+)/([^/]+) /questions/display.php?id=$1&referer=$2 [NC] 

Однако, когда я перейти к /questions/12345, я получаю ошибку 500 Internal Server - так ясно, что это не работает ,

Взглянув в журнале ошибок Apache, это показывает, что это то, что происходит:

AH00124: Запрос превысил лимит 10 внутренних переадресовывает из-за вероятную ошибку конфигурации. Используйте «LimitInternalRecursion», чтобы увеличить предел, если это необходимо. Используйте «LogLevel debug», чтобы получить обратную трассировку.

Что здесь не так, и что должно Я сделал?

+1

Не будет ли регулярное выражение '[^ /] +' также соответствовать тексту 'display.php? Id ='? Возможно, вам нужно настроить ваше регулярное выражение так, чтобы оно соответствовало только интересующему вас шаблону, то есть чем-то вроде '^ users/([0-9] +)'. Кроме того, когда вы получаете ошибку 500, что добавляется в ваши журналы Apache? 500 - это то, что возвращает пароли в браузер; ваш журнал должен содержать причину 500. – ghoti

+0

Правильно, поэтому вы переписываете '/ users/123 /' на '/users/display.php? id = 123', который затем переписывается на'/users/display. php? id = display.php? id = 123' и т. д. – ghoti

+0

@ghoti - ошибка в сообщении. Однако ваша идея 0-9, похоже, исправила ее ... как-то. Чак это в ответ. – ArtOfCode

ответ

1

Ваш переадресация ловят себя. :-)

Обратите внимание на атомы regex ([^/]+). Это означает «любой пробег одного или нескольких символов, которые не являются косой чертой». Текстовые display.php?id= матчей, так что на первый запрос для

/users/123 

вы переписаны

/users/display.php?id=123 

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

/users/display.php?id=display.php?id=123 

И ваш переписаны URL продолжает получать переписан, пока не достиг предела, как было отмечено в журнале.

Чтобы решить эту проблему, вы можете сделать свое начальное регулярное выражение более ограничительным.

RewriteRule ^users/([0-9]+) /users/display.php?id=$1 [NC] 

Вы также можете сказать перепишем двигатель, что данное правило является «последним» правилом, поэтому он не будет повторно обработать строку (или запустить его с помощью любых других правил):

RewriteRule ^users/([0-9]+) /users/display.php?id=$1 [NC,L] 

Наконец, вы можете добавить дополнительную защиту, говоря Apache не применять правила перезаписи, если запрошенный путь к файлу:

# Exempt requests to directories... 
RewriteCond %{REQUEST_FILENAME} !-d 

# Exempt requests directly to files... 
RewriteCond %{REQUEST_FILENAME} !-f 

# Rewrite /users/### 
RewriteRule ^users/([0-9]+) /users/display.php?id=$1 [NC,L] 

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

+0

Обратите внимание, что '? Id = 123' будет потерян, если петли переписывают –

2

Проблема заключается в том, что механизм перезаписи работает так, что вы переписываете, чтобы снова совпадать с тем же правилом. Вы можете попытаться добавить некоторые условия, чтобы предотвратить это: