1

Hi i'm trying to follow Mod_Rewrite for URL with multiple variables and edit it to suit my website but have a bit of a problem i have searched across the internet and could not really find anything which helps

I'm trying to turn example.com/editor/windows/chrome into this example.com?app=editor&os=windows&browser=chrome

Any ideas?

my current .htaccess file:

# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/?$ index.php?app=$1 [QSA]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?app=$1&os=$2&browser=$3 [QSA]
</IfModule>

I can get it to part work up-to example.com/editor/windows but can't get the third to include the browser

2 Answers 2

2

Your third rule doesn't include a capture group for the browser. This statement is missing:

RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ index.php?app=$1&os=$2&browser=$3 [QSA]

RewriteRules are applied from top to bottom until [L] is found. Thus, in your question both rules are applied (which might casue bad performance).

A more clean version would be,

# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on

# don't rewrite URLs for existing files, directories or links
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule .* - [L]

# now match the URIs according to OP needs
# Redirect example.com/editor and example.com/editor/ to example.com/index.php?app=editor and stop after this rule
RewriteRule ^([a-zA-Z0-9_-]+)/?$ index.php?app=$1 [QSA,L]
# Redirect example.com/editor/windows and example.com/editor/windows/ to example.com/index.php?app=editor&os=windows and stop after this rule
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?app=$1&os=$2 [QSA,L]
# Redirect example.com/editor/windows/chrome and example.com/editor/windows/chrome/ to example.com/index.php?app=editor&os=windows&browser=chrome and stop after this rule
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?app=$1&os=$2&browser=$3 [QSA,L]
</IfModule>

However, the last three RewriteRule rules can also be compiled to one:

RewriteRule ^([a-zA-Z0-9_-]+)(?:/([a-zA-Z0-9_-]+)(?:/([a-zA-Z0-9_-]+)))/?$ index.php?app=$1&os=$2&browser=$3 [QSA,L]
Sign up to request clarification or add additional context in comments.

4 Comments

You should explain how conditions are applied to rules, not compound the error. The easiest is to negate the conds and [OR] them so the first cond becomes RewriteCond %{REQUEST_FILENAME} -f [OR] and then follow these by RewriteRule ^ - [LAST, NC]
it was a straigt question here why the third case was not matching. The other rules indicated to me that the OP knows what these other rules indicated.
@TerryE I don't understand why you gave me -1 immediately without first discussing it (see other answers on this page). I tried hard to explain the reason for it (as opposed to other answers)
It's easy for me to flip a -1. I still get penalised for downvoting, but you'll remember my point. But I still prefer Jon Lin's soln.
1

As long as you don't mind having blank $_GET[] variables, you can reduce it all down to a single rule. Also not that you have 2 conditions that check for !-f and !-d. Those conditions only apply to the immediately following rule, and will not apply to any other rules unless you duplicate the condition.

So you can try:

# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)(?:/([a-zA-Z0-9_-]+)|)(?:/([a-zA-Z0-9_-]+)|)/?$ index.php?app=$1&os=$2&browser=$3 [L,QSA]
</IfModule>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.