Htaccess rewriting multiple variables - php

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]

Related

I want to redirect each, old URLs to its corresponding new rewritten URLs using htaccess

After much research, I have come to the conclusion that I am stuck and need help. Here is my htaccess:
ErrorDocument 404 http://website.com/404.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule . http://%1%{REQUEST_URI} [R=301,L]
RewriteRule contact contact.php [NC,L]
RewriteRule about display.php?id=2 [NC,L]
RewriteRule services display.php?id=4 [NC,L]
RewriteRule rss.xml?$ rss.php [L]
</IfModule>
This successfully created a rewritten URL for each display.php?id= query. Now that I have both URLs, how can I permanently redirect display.php?id=2 to about?
Thanks so much for your help!
First off, clear your browser cache. We don't want any cached permanent redirects which you already tried messing with our new logic:
#remove www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
#Use 302 redirects for debugging (the default if no redirect code is provided):
RewriteRule ^/?contact/?$ contact.php [NC,L,R]
RewriteRule ^/?about/?$ display.php?id=2 [NC,L,R]
RewriteRule ^/?services/?$ display.php?id=4 [NC,L,R]
RewriteRule ^/?rss.xml/?$ rss.php [NC,L,R]
If you're using google chrome, you can press ctrl+shift+j to open the developer tools. Then click the "network" tab and check the "disable cache" checkbox. Then try your requests again to see if it's working. Notice my code uses 302 redirects, this is the best practice for debugging. Once you can verify it's working as expected, you change change the 302 redirects to 301 redirects for production.
Edit:
To redirect everything the other way around, use this one instead:
#remove www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
#Use 302 redirects for debugging (the default if no redirect code is provided):
RewriteRule ^/?contact.php/?$ contact [NC,L,R]
RewriteCond %{QUERY_STRING} (^|&)id=2(&|$)
RewriteRule ^/?display\.php/?$ about? [NC,L,R]
RewriteCond %{QUERY_STRING} (^|&)id=4(&|$)
RewriteRule ^/?display\.php/?$ services? [NC,L,R]
RewriteRule ^/?rss.php/?$ rss.xml [NC,L,R]
Edit2:
#remove www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
#handle silent rewrites first:
RewriteCond %{THE_REQUEST} ^\w+\s+/?about
RewriteRule ^/?about/?$ /display.php?id=2&r=%1 [NC,L]
RewriteCond %{THE_REQUEST} ^\w+\s+/?contact
RewriteRule ^/?contact/?$ contact.php [NC,L]
RewriteCond %{THE_REQUEST} ^\w+\s+/?services
RewriteRule ^/?services/?$ display.php?id=4 [NC,L]
RewriteCond %{THE_REQUEST} ^\w+\s+/?rss\.xml
RewriteRule ^/?rss.xml/?$ rss.php [NC,L]
#handle redirects:
RewriteCond %{THE_REQUEST} ^\w+\s+/?display.php
RewriteCond %{QUERY_STRING} (^|&)id=2(&|$)
RewriteRule ^/?display\.php/?$ about? [NC,L,R]
RewriteCond %{THE_REQUEST} ^\w+\s+/?contact\.php
RewriteRule ^/?contact.php/?$ contact [NC,L,R]
RewriteCond %{THE_REQUEST} ^\w+\s+/?display\.php
RewriteCond %{QUERY_STRING} (^|&)id=4(&|$)
RewriteRule ^/?display\.php/?$ services? [NC,L,R]
RewriteCond %{THE_REQUEST} ^\w+\s+/?rss\.php
RewriteRule ^/?rss.php/?$ rss.xml [NC,L,R]
Edit3:
Actually, we can make use of the END flag here for slightly cleaner code:
#remove www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
#handle silent rewrites first:
RewriteRule ^/?about/?$ /display.php?id=2&r=%1 [NC,L,NS,END]
RewriteRule ^/?contact/?$ contact.php [NC,L,NS,END]
RewriteRule ^/?services/?$ display.php?id=4 [NC,L,NS,END]
RewriteRule ^/?rss.xml/?$ rss.php [NC,L,NS,END]
#handle redirects:
RewriteCond %{QUERY_STRING} (^|&)id=2(&|$)
RewriteRule ^/?display\.php/?$ about? [NC,L,R,END]
RewriteRule ^/?contact.php/?$ contact [NC,L,R,END]
RewriteCond %{QUERY_STRING} (^|&)id=4(&|$)
RewriteRule ^/?display\.php/?$ services? [NC,L,R,END]
RewriteRule ^/?rss.php/?$ rss.xml [NC,L,R,END]

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]

.htaccess rewrite rules for multiple parameters

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.)

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 allow only numbers after a certain point with https

i attached my current htaccess file below, it currently makes all my urls www with trailing slash at the end and if it is on and only on /prepaid/ it will be https.
i am tring to extend this functionality, where i can also accept requests from /prepaid/refill/a 10 digit phone number and have it be https as well
i started by adding this line at the bottom, but how would i extend the https part to allow from this path as well?
RewriteRule ^prepaid/refill/([0-9]+)/?$ index.php?p=prepaid&phone=$1 [L]
the current code
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L,R=301]
RewriteCond %{HTTPS} off
RewriteCond %{QUERY_STRING} !. [NC]
RewriteRule ^prepaid/?$ https://www.domain.com/prepaid/ [R=301,L]
RewriteCond %{HTTPS} on
RewriteRule ^prepaid/(.+) http://www.domain.com/prepaid/$1 [R=301,L,QSA]
RewriteRule ^prepaid/?$ index.php?p=prepaid [L]
RewriteRule ^prepaid/h2o-wireless/?$ index.php?p=prepaid&s=h2o [L]
RewriteRule ^prepaid/net10-wireless/?$ index.php?p=prepaid&s=net10 [L]
RewriteRule ^prepaid/page-plus-cellular/?$ index.php?p=prepaid&s=pageplus [L]
RewriteRule ^prepaid/red-pocket-mobile/?$ index.php?p=prepaid&s=redpocket [L]
RewriteRule ^prepaid/simple-mobile/?$ index.php?p=prepaid&s=simplemobile [L]
Have your full .htaccess like this:
RewriteEngine On
RewriteBase /
# force www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# force trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301]
# force HTTPS for /prepaid/ OR /prepaid/refill/([0-9]+)/
RewriteCond %{HTTPS} off
RewriteCond %{QUERY_STRING} !.
RewriteRule ^prepaid(/refill/[0-9]+)?/?$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NC]
# force HTTP for everything else
RewriteCond %{HTTPS} on
RewriteRule ^prepaid/(?!refill/[0-9]+).+$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NC]
# internal rewrites
RewriteRule ^prepaid/?$ index.php?p=prepaid [L,QSA,NC]
RewriteRule ^prepaid/h2o-wireless/?$ index.php?p=prepaid&s=h2o [L,QSA,NC]
RewriteRule ^prepaid/net10-wireless/?$ index.php?p=prepaid&s=net10 [L,QSA,NC]
RewriteRule ^prepaid/page-plus-cellular/?$ index.php?p=prepaid&s=pageplus [L,QSA,NC]
RewriteRule ^prepaid/red-pocket-mobile/?$ index.php?p=prepaid&s=redpocket [L,QSA,NC]
RewriteRule ^prepaid/simple-mobile/?$ index.php?p=prepaid&s=simplemobile [L,QSA,NC]
RewriteRule ^prepaid/refill/([0-9]+)/?$ index.php?p=prepaid&phone=$1 [L,QSA,NC]
to use https need write some ike this
with regular expressions, you must be caution and be:
\d+ - its only numberic characters
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule ^prepaid/refill/(\d+)/?$ index.php?p=prepaid&phone=$1 [L]

Categories