I’m playing with apache rewrite_mod (Apache/2.2.17 Win32) and encounter very weird behave of rewriteRule.
My script primarily rewrite infinite filter parameters named f1 .. f<infinity> from nice url and in loop adding them as query variables, add path as query, and page number.
It works flawlessly, but if I add one another rule (last rule in script)
RewriteRule ^(.+)\.html$ /index.php?path=$1.html [QSA]
which is for another cases, it change execution of rewriterule at start of script.
Input URL:
http://testing.loc/some/thing/index0-f1-nice-cars-f2-planes-f3-karts-f4-bike.html
Expected result in PHP after all rewrites:
$_SERVER[QUERY_STRING] => path=some/thing/&page=0&f1=nice-cars&f2=planes&f3=karts&f4=bike
$_SERVER[SCRIPT_NAME] => /index.php
Script look like this (next part is flawlessly functional):
# from: some/thing/index0-f1-nice-cars-f2-planes-f3-karts-f4-bike.html
# to: some/thing/index0.html?f=-f1-nice-cars-f2-planes-f3-karts-f4-bike
RewriteRule ^(.*/?index[0-9]*)((?:-f[0-9]+-.+?)+)\.html$ /$1.html?f=$2 [QSA]
# from: some/thing/index0.html?f=-f1-nice-cars-f2-planes-f3-karts-f4-bike
# to index.php?path=some/thing/&page=0&f=-f1-nice-cars-f2-planes-f3-karts-f4-bike
# ( $1 ) ( $2 )
RewriteRule ^(.+/{0,1})index([0-9]*)\.html$ /index.php?path=$1&page=$2 [QSA]
# while in f is something like "f1-nice-cars" (for example)
# remove "f1-nice-cars" from f and add as query "f1=nice-cars"
# (%1) ( %2 ) ( %3)( %4 )
RewriteCond %{QUERY_STRING} ^(.*)&f=-(f[0-9]+)-(.+?)((?:-f[0-9]+-.+)*)$
RewriteRule ^index\.php$ /index.php?%1&%2=%3&f=%4 [L]
# remove empty "f=" from query
RewriteCond %{QUERY_STRING} ^(.*)&f=$
RewriteRule ^index\.php$ /index.php?%1
here, after rules is url in shape:
index.php?path=some/thing/&page=0&f1=nice-cars&f2=planes&f3=karts&f4=bike
Without next rule in script is everything perfectly functional. But if I add it, this rule itself do nothing, but rewrite_mod add something more to subtitution at start of script.
# rewrite rule for other paths without filters
RewriteRule ^(.+)\.html$ /index.php?path=$1.html [QSA]
Actually after run all script result is:
index.php?path=/some/thing/index0.html/some/thing/index0&f1=nice-cars&f2=planes&f3=karts&f4=bike
I found resolution of this problem.
When 2 rules match URL at one pass of .htaccess, then apache rewrite_mod use method “add path info postfix” (its something like bug or feature), which ruin path of request. So when I added flag [L] to that 2 rules, result is OK.
I thinked that apache pass .htaccess sequentially and does not matter on next rules…