Я хочу сделать mod_rewrite так, чтобы:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

Любые запросы к users/ отправляются index.php?login=(whatever).

RewriteRule ^users/(.+) ?login=$1 [NE,L]

Любые другие запросы, кроме users/, отправляются в то же место.

RewriteRule ^(.+) users/?login=$1 [NE,L]

Но вторая часть производит 500 Internal Server Error

Меня попросили объяснить это, поэтому вот несколько примеров:

  • если существует "domain.com/aaa/", он переходит в "domain.com/aaa/"
  • если "domain.com/bbb/" не существует, он переходит к "domain.com/users/?login=bbb"
  • если существует "domain.com/ccc.html, он переходит к" domain.com/ccc.html "
  • если "domain.com/ddd.html не существует, он переходит к" domain.com/users/?login=ddd.html "
  • между тем, «domain.com/users/eee» переходит к «domain.com/users/?login=eee», поскольку это основное условие, а второе условие - резервное или более общее.
1
Ben Coffin 29 Июн 2017 в 00:01
Во второй части непонятно, чего вы пытаетесь достичь, что вы подразумеваете под «любые другие запросы, не относящиеся к пользователям /, идут в то же место»? То же, что и что? Ваш другой идет в /index.php, а этот идет в /users/?
 – 
user2493235
29 Июн 2017 в 00:06
1
* технически пример 4 должен идти по адресу: "domain.com/users/?login=ddd.html"
 – 
Ben Coffin
29 Июн 2017 в 00:19

1 ответ

Лучший ответ

Это должно сработать. Вы должны повторить условия, они не переносятся на следующее правило.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^users/(.+)$ /users/?login=$1 [NE,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /users/?login=$1 [NE,L]

Предполагая, что каталог /users/ действительно существует.

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

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

RewriteRule ^users/(.+)$ /users/?login=$1 [NE,L]
RewriteRule ^(.+)$ /users/?login=$1 [NE,L]
1
user2493235user2493235 29 Июн 2017 в 00:24
Он просто говорит: «Если условия выполнены, прекратите обработку здесь и ничего не меняйте».
 – 
user2493235
29 Июн 2017 в 00:31
... в противном случае соблюдайте следующие два правила, какое из них применимо раньше?
 – 
Ben Coffin
29 Июн 2017 в 00:31
1
По сути, да. Если первый из них совпадает, он прекращает обработку, а второй никогда не запускается (потому что тогда он существует и попадает в указанную выше проверку каталога, когда происходит следующая итерация).
 – 
user2493235
29 Июн 2017 в 00:33
И в моем случае (заданный вопрос) он никогда не попадает в последнее правило, поэтому никогда не останавливается (500)?
 – 
Ben Coffin
29 Июн 2017 в 00:34
1
В вашем случае я думаю, что последнее правило зацикливалось, потому что оно продолжало работать каждый раз без проверки, чтобы остановить его, пока не будет достигнут предел цикла. На самом деле нужно проверить журнал ошибок, чтобы быть уверенным.
 – 
user2493235
29 Июн 2017 в 00:36