.htaccess rewrite rules for multiple parameters - php

Rewriting the following 3 URLs
http://example.com/index.php?page=search
to
http://example.com/search
http://example.com/index.php?page=profile&value=myname
to
http://example.com/myname
http://example.com/index.php?page=stats&type=daily
to
http://example.com/stats/daily
Current .htaccess is written as the following:
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} /index\.php\?page=([^\s&]+)&value=([^\s&]+) [NC]
RewriteRule ^ index/%1/%2? [R=302,L,NE]
RewriteCond %{THE_REQUEST} /index\.php\?page=([^\s&]+)&type=([^\s&]+) [NC]
RewriteRule ^ index/%1/%2? [R=302,L,NE]
RewriteCond %{THE_REQUEST} /index\.php\?page=([^\s&]+) [NC]
RewriteRule ^ index/%1/? [R=302,L,NE]
RewriteRule ^index/([^/]+)/([^/]+)/?$ /index.php?page=$1&value=$2 [NC,L,QSA]
RewriteRule ^index/([^/]+)/([^/]+)/?$ /index.php?page=$1&type=$2 [NC,L,QSA]
RewriteRule ^index/([^/]+)/?$ /index.php?page=$1 [NC,L,QSA]
I need to remove /index/ from the first and third URL, and /index/profile/ from the second one.
All comments & suggestions are welcomed.

You can't have both the search and profile be the same regex pattern. For example, if someone requests:
http://example.com/index/foo
Are they trying to go to a page called "foo" or go to a profile of a user named "foo"? You need to add something that separates the two, maybe something like:
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} /index\.php\?page=profile&value=([^\s&]+) [NC]
RewriteRule ^ profile/%1? [R=302,L,NE]
RewriteCond %{THE_REQUEST} /index\.php\?page=([^\s&]+)&type=([^\s&]+) [NC]
RewriteRule ^ page/%1/%2? [R=302,L,NE]
RewriteCond %{THE_REQUEST} /index\.php\?page=([^\s&]+)(\ |$) [NC]
RewriteRule ^ page/%1? [R=302,L,NE]
RewriteRule ^profile/([^/]+)/?$ /index.php?page=profile&value=$1 [NC,L,QSA]
RewriteRule ^page/([^/]+)/([^/]+)/?$ /index.php?page=$1&type=$2 [NC,L,QSA]
RewriteRule ^page/([^/]+)/?$ /index.php?page=$1 [NC,L,QSA]
This makes your urls look like:
http://example.com/profile/myname
http://example.com/page/search
http://example.com/page/stats/daily

Presumably these are 3 exceptions (special cases) to the current rules, so the existing rules should not change. (?)
Add the following "special cases" immediately after your RewriteBase directive, before your existing rules:
RewriteCond %{THE_REQUEST} /index\.php\?page=(search)
RewriteRule ^ /%1? [R=302,L]
RewriteCond %{THE_REQUEST} /index\.php\?page=profile&value=(myname)
RewriteRule ^ /%1? [R=302,L]
RewriteCond %{THE_REQUEST} /index\.php\?page=(stats)&type=(daily)
RewriteRule ^ /%1/%2? [R=302,L]
If you then need to internally rewrite these specific URLs back into the "real" parameterized versions then, at the end of your .htaccess file:
RewriteRule ^(search)$ /index.php?page=$1 [L,QSA]
RewriteRule ^(myname)$ /index.php?page=profile&value=$1 [L,QSA]
RewriteRule ^(stats)/(daily)$ /index.php?page=$1&type=$2 [L,QSA]
(I've removed the NC flag - add this back if you really need it.)

Related

rewriteCond request with htaccess

I would like to accomplish the followings (rewrite not redirect):
searchPage.php?crs_category=variable like searchPage.php?crs_category=business to category/business or category/business/ case in-sensitive
You can also directly access category/name which is the rewrite of searchPage
index.php/name to page/name case in-sesitive. note this is a rewrite not a redirect and i would like access the index.php/name just with a clean url.
You can also directly access page/name which is the rewrite of index.php/name
Note:
- it needs to take into account spaces such as if a user click on searchPage.php?crs_category=html%20and%css it would rewrite the url to category/html and css
Tried:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} /searchPage.php\?crs_category=([^\s]+) [NC]
RewriteRule ^category/%1? [NE,NC,R,L]
RewriteRule ^category/([^/]+)/?$ /searchPage.php?crs_category=$1 [QSA,L,NC]
RewriteCond %{THE_REQUEST} /index\.php/(\S+) [NC]
RewriteRule ^ /page/%1 [NE,R,L]
RewriteRule ^page/([^/]+)/?$ index.php/$1 [NC,L]
Problem:
For some reason the request doesn't work for these lines:
RewriteCond %{THE_REQUEST} /searchPage.php\?crs_category=([^\s]+) [NC]
RewriteRule ^category/%1? [NE,NC,R,L]
In addition, I am not sure who take into account white space. where if its searchPage.php?crs_category=html%20andcss it leads to category/html and css disregarding the spacing code
Update:
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteBase /
# keep replacing space to hyphen until there is no space use internal rewrite
RewriteRule ^([^\s%20]*)[\s%20]+(.*)$ $1-$2 [E=NOSPACE:1]
# when there is no space make an external redirection
RewriteCond %{ENV:NOSPACE} =1
RewriteRule ^([^\s%20]+)$ $1 [R=301,L]
RewriteCond %{THE_REQUEST} /searchPage\.php\?crs_category=([^&]+?)\s [NC]
RewriteRule ^ category/%1? [NE,R,L]
RewriteCond %{THE_REQUEST} /index\.php/(\S+) [NC]
RewriteRule ^ page/%1 [NE,R,L]
RewriteRule ^category/([^/]+)/?$ searchPage.php?crs_category=$1 [QSA,L,NC]
RewriteRule ^page/([^/]+)/?$ index.php/$1 [NC,L]
You should be matching / after index.php not ?:
You can use these rules:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} /searchPage\.php\?crs_category=([^&]+?)\s [NC]
RewriteRule ^ category/%1? [NE,R,L]
RewriteCond %{THE_REQUEST} /index\.php/(\S+) [NC]
RewriteRule ^ page/%1 [NE,R,L]
# keep replacing space to hyphen until there is no space use internal rewrite
RewriteRule ^(\S*)\s+(.*)$ $1-$2 [E=NOSPACE:1,DPI]
# when there is no space make an external redirection
RewriteCond %{ENV:NOSPACE} =1
RewriteRule ^(\S+)$ $1 [NE,R=302,L]
RewriteRule ^category/([^/]+)/?$ searchPage.php?crs_category=$1 [QSA,L,NC]
RewriteRule ^page/([^/]+)/?$ index.php/$1 [NC,L]

RewriteRule blocking RewriteCond & RewriteRule after it

If this is a duplicate then I am really sorry, but I used google and also search here and could not find anything that would work for me. Maybe I just don't know what exactly to search for.
Anyway, back to my question:
I am trying to change old ugly URLs to nicer urls (wanted to have news/XXX/XY but relative links defeated me), so I wrote couple lines of code to my .htaccess and tested them (well, I actually used same code on my other page for redirect, so I know it does work). I get redirected from /news.php to /news, but the query string magic is not working at all...
RewriteRule ^news.php$ /news [L,NC,R=301]
RewriteRule ^news?$ /news.php [L,NC]
RewriteCond %{THE_REQUEST} /news\?rowstart=([^\s]+) [NC]
RewriteRule ^ news-row-%1? [R=302,L]
RewriteCond %{THE_REQUEST} /news\?readmore=([^\s]+)&rowstart=([^\s]+) [NC]
RewriteRule ^ news-%1-%2? [R=302,L]
RewriteCond %{THE_REQUEST} /news\?readmore=([^\s]+) [NC]
RewriteRule ^ news-%1? [R=302,L]
None of the RewriteRules after first one gets executed. But if I change my .htaccess like this:
RewriteRule ^news.php$ /news [L,NC,R=301]
RewriteCond %{THE_REQUEST} /news\?rowstart=([^\s]+) [NC]
RewriteRule ^ news-row-%1? [R=302,L]
RewriteCond %{THE_REQUEST} /news\?readmore=([^\s]+)&rowstart=([^\s]+) [NC]
RewriteRule ^ news-%1-%2? [R=302,L]
RewriteCond %{THE_REQUEST} /news\?readmore=([^\s]+) [NC]
RewriteRule ^ news-%1? [R=302,L]
RewriteRule ^news?$ /news.php [L,NC]
then it works. I tried using /\?bla - /news\?bla - /news\.php\?bla etc. Nothing actually worked.
Does somebody have any Idea why its behaving like this and how to fix it? It looks like it does not recognize the news after it starts loading from news.php file.
I am completly lost, as I don't work with .htaccess that often. Any ideas?
I actually ended up using this:
#########################
# NICE URLS QUERIES #
#########################
RewriteCond %{THE_REQUEST} /news(?:\.php|)\?rowstart=([^\s]+) [NC]
RewriteRule ^ news-page-%1? [R=302,L]
RewriteCond %{THE_REQUEST} /news\(?:\.php|)\?readmore=([^\s]+)&rowstart=([^\s]+) [NC]
RewriteRule ^ news-%1-%2? [R=302,L]
RewriteCond %{THE_REQUEST} /news(?:\.php|)\?readmore=([^\s]+) [NC]
RewriteRule ^ news-%1? [R=302,L]
RewriteRule ^news-([0-9]+)-([0-9]+)?$ news.php?readmore=$1&rowstart=$2 [L,QSA,NC]
RewriteRule ^news-([0-9]+)/?$ news.php?readmore=$1 [L,QSA,NC]
RewriteRule ^news-page-([0-9]+)/?$ news.php?rowstart=$1 [L,QSA,NC]
#######################
# OTHER NICE URLS #
#######################
RewriteRule ^news.php$ /news [L,NC,R=301]
RewriteRule ^news?$ /news.php [L,NC]
The first thing you need to make sure you're doing is putting all the redirects first. That is, every rule that has the R flag needs to be before the rules that don't. But it looks like you're not matching the - style URLs to rewrite them BACK to the version with the query string. So I think you really want something like this (you can get rid of the .php extension while you get rid of the query string):
RewriteCond %{THE_REQUEST} \ /+news\.php(\ |$)
RewriteRule ^ /news [L,R=301]
RewriteCond %{THE_REQUEST} \ /+news(?:\.php|)\?rowstart=([\ &]+)
RewriteRule ^ /news-row-%1? [L,R=301]
RewriteCond %{THE_REQUEST} \ /+news(?:\.php|)\?readmore=([^&]+)&rowstart=([\ &]+)
RewriteRule ^ /news-%1-%2? [L,R=301]
RewriteCond %{THE_REQUEST} \ /+news(?:\.php|)\?readmore=([\ &]+)
RewriteRule ^ /news-%1? [L,R=301]
## Now, internally rewrite the request back to the query string and php extension
RewriteRule ^news$ /news.php [L]
RewriteRule ^news-row-(.*)$ /news.php?rowstart=$1 [L,QSA]
RewriteRule ^news-(.*)-(.*)$ /news.php?readmore=$1&rowstart=$2 [L,QSA]
RewriteRule ^news-(.*)$ /news.php?readmore=$1 [L,QSA]

Multiple URL parameter Rewrite rule doesn't work

i'm trying to make the URL write rule work but it doesn't show any data after the rule is applied.
The URL (without rewrite)
http://example.com/categories.php?explore=design&sc=css
The URL (with rewrite)
http://example.com/design/css/
The Rewrite Rule i have
#Level-1
RewriteCond %{THE_REQUEST} /categories\.php\?explore=([^\s&]+) [NC]
RewriteRule ^ categories/%1/? [R=302,L,NE]
RewriteRule ^categories/([^/]+)/?$ categories.php?explore=$1 [NC,L,QSA]
#Level-2
RewriteCond %{THE_REQUEST} /categories\.php\?explore=([^\s&]+)&sc=([^\s&]+) [NC]
RewriteRule ^ categories/%1/%2/? [R=302,L,NE]
RewriteRule ^categories/([^/]+)/?$ categories.php?explore=$1&sp=$2 [NC,L,QSA]
The above does work for only 1 Level, Whats wrong with the 2nd Level?
Try with this .htaccess:
RewriteCond %{THE_REQUEST} /categories\.php\?explore=([^\s&]+)&sc=([^\s&]+) [NC]
RewriteRule ^ categories/%1/%2/ [R=302,L,NE]
RewriteCond %{THE_REQUEST} /categories\.php\?explore=([^\s&]+) [NC]
RewriteRule ^ categories/%1/ [R=302,L,NE]
RewriteRule ^categories/([^/]+)/([^/]+)/?$ categories.php?explore=$1&sc=$2 [NC,L,QSA]
RewriteRule ^categories/([^/]+)/?$ categories.php?explore=$1 [NC,L,QSA]
(and you wrote sp with the first and sc with the last...)

how to rewrite multiple get variables using htaccess

i have a page with search form(fields: make,model,year,mileage,price)
on form submit url is:
http://www.example.com/buy-car.php?make=xxx&model=xxx&mileage=100;10000&year=2000;2015&price=20000;60000&sort=date;DESC
i want to rewrite to look like:
http://www.example.com/buy-car/xxx/xxx/100;10000/2000;2015/20000;60000/date;DESC
Note: query string may or may not contain all the variable
i tried multiple rules but still not getting what i want
RewriteCond %{THE_REQUEST} /buy-car\.php\?make=([^\s&]+)&model=([^\s&]+)&year=([^\s&]+)\&mileage=([^\s&]+)\&price=([^\s&]+)\s [NC]
RewriteRule ^ buy-car/%1/%2/%3/%4/%5? [R=302,L]
RewriteRule ^buy-car/([\w-]+)/([\w-]+)/([\^;a-zA-Z0-9_-]+)/([\^;a-zA-Z0-9_-]+)/([\^;0-9-]+)/?$ buy-car.php?make=$1&model=$2&year=$3&mileage=$4&price=$5 [L,QSA,NC]
RewriteCond %{THE_REQUEST} /buy-car\.php\?make=([^\s&]+)&model=([^\s&]+)&year=([^\s&]+)\&mileage=([^\s&]+)\s [NC]
RewriteRule ^ buy-car/%1/%2/%3? [R=302,L]
RewriteRule ^buy-car/([\w-]+)/([\w-]+)/([\^;a-zA-Z0-9_-]+)/([\^;a-zA-Z0-9_-]+)/?$ buy-car.php?make=$1&model=$2&year=$3&mileage=$4 [L,QSA,NC]
RewriteCond %{THE_REQUEST} /buy-car\.php\?make=([^\s&]+)&model=([^\s&]+)&year=([^\s&]+)\s [NC]
RewriteRule ^ buy-car/%1/%2/%3? [R=302,L]
RewriteRule ^buy-car/([\w-]+)/([\w-]+)/([\^;a-zA-Z0-9_-]+)/?$ buy-car.php?make=$1&model=$2&year=$3 [L,QSA,NC]
RewriteCond %{THE_REQUEST} /buy-car\.php\?make=([^\s&]+)&model=([^\s&]+)\s [NC]
RewriteRule ^ buy-car/%1/%2? [R=302,L]
RewriteRule ^buy-car/([\w-]+)/([\w-]+)/?$ buy-car.php?make=$1&model=$2 [L,QSA,NC]
RewriteCond %{THE_REQUEST} /buy-car\.php\?year=([^\s&]+)\s [NC]
RewriteRule ^ buy-car/%1? [R=302,L]
RewriteRule ^buy-car/([\^;0-9-]+)/?$ buy-car.php?year=$1 [L,QSA,NC]
RewriteCond %{THE_REQUEST} /buy-car\.php\?make=([^\s&]+)\s [NC]
RewriteRule ^ buy-car/%1? [R=302,L]
RewriteRule ^buy-car/([\w-]+)/?$ buy-car.php?make=$1 [L,QSA,NC]
what could be the solution.
thanks
Rather than maintaining so many rules like that and possibly more due to optional query parameters I strongly suggest using front controller .htaccess like this:
DirectryIndex index.php
RewriteEngine On
RewriteBase /
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) index.php?uri=$1 [L,QSA]
Then use $_GET['uri'] in the php code to get requested URI and process them.

Htaccess rewriting multiple variables

I am completely dumb when it comes to .htaccess, even through my numerous attempts to learn the basics. So I am here:
This is my current .htaccess:
RewriteEngine on
RewriteRule ^$ /splash [L,R=301]
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
RewriteRule ^([a-z0-9-]+)/?$ /index.php?cat=$1 [L,NC,QSA]
I would like to keep its current functionality and add two things so its like:
(keep) redirecting address without variable to domain.com/splash
(keep) redirecting of address without WWW to address with WWW (http://domain.com/xx to http://www.domain.com/xx)
(keep) make it rewrite from http://www.domain.com/aa to http://www.domain.com/index.php?cat=aa
(add) make it rewrite from http://www.domain.com/aa/bb to http://www.domain.com/index.php?cat=aa&product=bb
(add) remove trailing slash at the end if present
You can use:
RewriteEngine on
RewriteRule ^$ /splash [L,R=301]
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s(.+?)/+[?\s]
RewriteRule ^(.+?)/$ /$1 [R=301,L]
RewriteRule ^([a-z0-9-]+)/?$ /index.php?cat=$1 [L,NC,QSA]
RewriteRule ^([a-z0-9-]+)/([a-z0-9-]+)/?$ /index.php?cat=$1&product=$2 [L,NC,QSA]

Categories