Pregunta

I'm new to mod_rewrite but am trying my best to fix up my site with clean URLs.

Using RewriteRule I can get it so you can type in a clean URl and get to the right page, but what I'm having trouble with is automatically redirecting to the clean URL if a "messy" one is used (which is highly possible due to user submitted links and content etc)

Now, I have this bit of code which I found on another .htaccess forum, and it works in one situation, but not another. I'll explain:

# FORCE CLEAN URLS
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php\?(.*)=([^\s]+) [NC]
RewriteRule ^ %1\/%2? [R=301,L]

This works fine on an address like this, for example: www.domain.com/index.php?cmd=login it automatically redirects to www.domain.com/cmd/login

But the problem comes when there is more than one query, like: www.domain.com/index.php?cmd=view-profile&user=bob

I can't figure out how to make it sort out that kind of URL when there could be up to 3 or more queries in the address. I'm not fully competent with regex, so my attempts to amend the code snippet I have has failed thus far.

Any help would be appreciated! I would like them to be 301 redirects so that the site can get indexed properly and be SEO compliant no matter what type of clean or messy URL is used, but I'm open to suggestions!

EDIT

After playing around with the regex for a few hours, I've progressed but got stumped again.

If I make the expression to this:

index\.php\?(.*)=([^\s]+)(&(.*)=([^\s]+))?+
$1/$2/$3/$4/$5

It will match these 3 URLs from index.php onwards:

http://site.com/index.php?cmd=shop&cat=78

http://site.com/index.php?cmd=shop

http://site.com/index.php?cmd=shop&cat=78&product=68

BUT the resulted output varies depending on which it is. These are my results:

http://site.com/cmd=shop&cat/78///

http://site.com/cmd/shop///

http://site.com/cmd=shop&cat=78&product/68///

I'm nit sure how to get it to treat certain parts as optional so it groups properly.

¿Fue útil?

Solución

You'll need to deal with each number of pairs of parameters separately. The one you have can be used to handle one name/value pair, then approach it similarly for 2, and 3 (and 4 if needed):

# To handle a single name/value pair in the query string:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php\?([^&=]+)=([^&\ ]+)(\ |$) [NC]
RewriteRule ^ /%1\/%2? [R=301,L]

# To handle 2:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php\?([^&=]+)=([^&\ ]+)&([^&=]+)=([^&\ ]+)(\ |$) [NC]
RewriteRule ^ /%1\/%2/%3/%4? [R=301,L]

# To handle 3:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php\?([^&=]+)=([^&\ ]+)&([^&=]+)=([^&\ ]+)&([^&=]+)=([^&\ ]+)(\ |$) [NC]
RewriteRule ^ /%1\/%2/%3/%4/%5/%6? [R=301,L]

Basically, you're adding another &([^&=]+)=([^&\ ]+) before the check for the end of the request, (\ |$), and adding another /%#/%# to the end of the target URI, where the #'s are appropriate incremented backreferences.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top