Às vezes pode parecer que o
RewriteRule executa duas vezes, mesmo usando a diretiva
[L].
A verdade é que
ele executa, mesmo! Mas só quando há alteração na URL.
A diretiva
[L] impede a execução do código que vem em seguida, mas se houve alteração na URL, a nova URL será reprocessada desde o início.
Há muitas soluções para isso (com o uso do
RewriteCond, por exemplo), mas a que eu uso é colocar, no início das regras, uma regra dizendo que, se a URL já está do jeito que eu quero, não muda nada:
RewriteEngine on
# index is the last rule - is what I want, so doesn't change anything and go to it (thank's to [L])!
RewriteRule ^index.php$ - [L,QSA]
# get user id - URL changed, so [L] will cause the new URL to be reparsed - and so it will be matched on the above rule.
RewriteRule ^user/(.*)$ index.php?user=$1 [L,QSA]
# in case of user/..., following rules don't apply, since the above rule has [L]
# ...
Veja esta dica em
inglês.