.htaccess redirect only if GET parameter exists - php

I have a client with an old website without 'pretty' URLs. So currently it looks like this:
http://www.domain.com/?w=42&a=5&b=3
The parameter values are numbers only.
Now they want to move the old site to a subdomain and main (www) domain would be home to a new website (WP with SEO friendly URLs).
Now what I would like to do is redirect all requests that come to the /?w=<num> (and ONLY those) to sub.domain.com/?w=<num>, so that existing links (mostly from Google) get redirected to the subdomain page, while the new page works serving new content thorough pretty URLs.
I tried this:
# This works, but redirects the entire www.domain.com
# to sub.domain.com no mather what
RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://sub.domain.com/$1 [R=301,L]
# But this DOESN'T work
RewriteRule ^/?w(.*) http://sub.domain.com/?w$1 [R=301,L]
# Also tried to redirect 'by hand', but DIDN'T work either
Redirect 301 /?w=42 http://sub.domain.com/?w=42
What am I doing wrong? I searched high and low but always end up with this kind of suggestions. Or maybe I'm just searching for wrong keywords ...
Thank you!

You can't match against the query string inside a rewrite rule or a redirect directive. You need to match against the %{QUERY_STRING} variable. Try:
RewriteCond %{QUERY_STRING} (^|&)w=[0-9]+(&|$)
RewriteRule ^(.*)$ http://sub.domain.com/$1 [L,R=301]
Note that the query string gets automatically appended to the end of the rule's destination.

Just for documentation: If you want to redirect one directory (path) only if there is a URL parameter present, from one path to another, while maintaining the URL parameter, you can use this in your htaccess file:
# /programs/?id=1 to new path /loadprog/?id=1
RewriteCond %{REQUEST_URI} ^/programs/
RewriteCond %{QUERY_STRING} id=
RewriteRule ^programs\/$ /loadprog/$1 [R=301,L]
I am sure this will help others since I stumbled over the question above trying to find this answer.

Related

htaccess rules to rewrite subfolder to a GET variable

I'm not very experienced with htaccess. today I fail in writing an .htaccess to rewrite a url.
What I want:
My project is hosted on a subdomain e.g. sub.domain.com
My htaccess should manage:
sub.domain.com should redirect to www.domain.com (Redirect 301, that's clear)
subfolders should be put as GET variable e.g. sub.domain.com/test to www.domain.com?var=test
the subfolder /admin shouldn't be redirected
Thanks in advance for tips!
This should do it for you:
RewriteEngine on
RewriteCond %{HTTP_HOST} =sub.example.com
# Following condition added to support changed requirement, see comments
RewriteCond %{QUERY_STRING} !(?:^|&)var=
RewriteCond %{REQUEST_URI} !^/admin/
RewriteRule ^(.*)$ http://www.example.com/?var=$1 [R=301,L]
This will drop any query string that was in the original request. If you want to keep any query string, and just append 'var=...' to it, then add QSA to the flags at the end of the last line, separated by a comma.

How to orgnize 301 redirects only for pages with get parmeters?

Here is a quick SEO question. We decided to split our web site into two different sites. Google has already crawled 50K pages which we want to move to another domain name. My question is what would be the best way to deal with it as we want only certain URLs to be redirected not the whole website. Should I do mode rewire catch the get parameters and send them over to the new domain name? or should I do it with php headers?
olddomain.com becomes oldomain.com and newdomain.com
oldomain.com?name=jw&gsurname=black --> newdomain.com?name=jw&gsurname=black
oldomain.com with any other url structure should stay the same
You should be able to use the RewriteCond and RewriteRule directives together to match against query string values, like so:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^name=([^&]+)&gsurname=([^&]+)$
RewriteRule ^(.*)$ http://newdomain.com?name=%1&gsurname=%2 [R=301,L]
If you mean exactly that set of query parameters:
RewriteCond %{QUERY_STRING} ^name=([^&]+)&gsurname=(.*)$
RewriteRule ^/$ http://newdomain.dom [R=301, L]
The RewriteCond looks at the query string and checks that the first parameter is name and the second parameter is gsurname. The ([^&]+) collects all of the characters until it finds an ampersand (^& means not ampersand). The (.*)$ collects characters until the end of the query string ($).
If the RewriteCond is true, then the RewriteRule redirects to the new domain. The query string is automatically passed along as-is.

.htaccess Apache mod rewrite rule always giving a redirect loop

I am normally fine at writing apache redirects but this particular client's server has been giving me problems :c
I am trying to redirect all sub-pages to the main domain but I am always getting a infinite redirection loop.
Here's my .htaccess file - what am I doing wrong?
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^test$ "http\:\/\/example\.com\/" [R=301,L]
RewriteCond %{REQUEST_URI} !"^/$"
RewriteRule ^.*$ "http\:\/\/example\.com\/" [R=301,L]
whoa redirect infinity! but say if I do something like this:
RewriteRule ^test$ "http\:\/\/example\.com\/" [R=301,L]
This will redirect http://example.com/test to http://example.com and bam, it works!
Any guidance would be appreciated. Thanks!
// EDIT
The issue is that we have a mailing list plugin which sends the user a confirmation email. After clicking the confirmation button in the confirm email the user is redirected back to our site with a long query string appended to http://example.com/. The query string is generated so it's never going to be the same.
Here's an example of one of the query strings:
http://example.com/?has_media=false&fan=https%3A%2F%2Fapp.topspin.net%2Fapi%2Fv1%2Ffan%2Fshow%2F63451204%3Fartist_id%3D12053%26auth%3D96419cab29f59a342cde9ca3c0c20b58&campaign=https%3A%2F%2Fapp.topspin.net%2Fapi%2Fv1%2Fartist%2F12053%2Fcampaign%2F10151864
// Edit 2
I tried #Jon Lin's example and the page loads strangely but it does load. Basically, the correct domain loads in some browsers but the assets (CSS, and images do not) and the networks inspector is showing these paths as permanently moved also :s
Try changing your last rule to:
RewriteRule !^(?:index\.(html?|php)|)$ http://example.com/ [R=301,L]
The reason is that after the directory index is mapped (to something like index.php), the rules get reprocessed again, and thus the extra redirect.
Note that the query string is still going to be at the end. That's because there is no way to match against the query string in a RewriteRule. You need to match against the %{QUERY_STRING} variable. In order to get rid of the query string, you need to add a ? to the end of http://example.com/.

How to write an htaccess 301 Redirection rule to redirect from php to html

I have a problem (it's probably a simple one but I've never had the need to write regex)
A SEO specialist told me to make pretty URLs so I did with the .htaccess file the CMS provides.
But now he requires me to redirect the old URLs to new ones.
This doesn't work
RewriteRule ^index.php?page=kontakt$ /kontakt.html [R=301,L]
and also this (wich was supposed to redirect to the main page from the index.php file)
RewriteRule ^index.php$ / [R=301,L]
has resulted in sitename.com/?page=kontakt, so now I also have to redirect this.
How do I fix this?
RewriteRule only matches the base URL without the query string. You need an additional RewriteCond for it to work.
RewriteCond %{QUERY_STRING} ^page=kontakt$
RewriteRule ^index.php$ /kontakt.html [R=301,L]
EDIT:
Apparently query string gets preserved in this case, so you're probably getting /kontakt.html?page=kontakt
To discard original query string you need to put ? after URL.
RewriteRule ^index.php$ /kontakt.html? [R=301,L]

Rewrite url which redirects to page on webserver

I am trying to get a page with a query string to redirect to a nicer looking url then get that url and transfer it back to the original query string but without redirecting (i.e. without changing the url)
At the moment I am getting a redirect loop (for obvious reasons) but I was hoping for a way to stop this.
This is my code in my htaccess file
#rewrite search querystring
#/search/'apartment'/2_bedrooms/price_0-500000/town_W4/development_18,SW5/
RewriteRule ^search/([^/]+)/([^/]+)_bedrooms/price_([^/]+)-([^/]+)/town_([^/]+)/development_([^/]+) /search.php?propertytype=$1&bedrooms=$2&minprice=$3&maxprice=$4&location=$5&development=$6 [NC]
RewriteCond %{QUERY_STRING} propertytype=([^/]+)&bedrooms=([^/]+)&minprice=([^/]+)&maxprice=([^/]+)&location=([^/]+)&development=([^/]+)
/search/$1/$2_bedrooms/price_$3-$4/town_$5/development_$6 [R,L]
RewriteRule ^(.*)$ /search/%1/%2_bedrooms/price_%3-%4/town_%5/development_%6? [R,L]
So what it is meant to do is:
user has been taken to:
http://www.domain.com/search/?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
This page is the actual page on the server where the data is coming from, however I want the user to see.
http://www.domain.com/search/dev/2_bedrooms/price_0-10000000/town_W1/development_W1/
Is it possible to do this without a redirect loop.
Thanks for your help
EDIT I'm thinking it could be done with the rewrite flags but I'm not sure, I'm quite new to the Rewrite Engine
Edited:
Here is a complete (and working) solution for you:
RewriteEngine On
# User gets here:
# http://localhost/search/?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
# He is explicit redirected to here:
# http://localhost/search/dev/2_bedrooms/price_0-10000000/town_W1/development_W1/
# Internally, apache calls this:
# http://localhost/search.php?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
RewriteRule ^search/([^/]+)/([^/]+)_bedrooms/price_([^/]+)-([^/]+)/town_([^/]+)/development_([^/]+) search.php?propertytype=$1&bedrooms=$2&minprice=$3&maxprice=$4&location=$5&development=$6 [NC,PT]
RewriteCond %{QUERY_STRING} propertytype=([^/]+)&bedrooms=([^/]+)&minprice=([^/]+)&maxprice=([^/]+)&location=([^/]+)&development=([^/]+)
RewriteRule ^search/(.*)$ /search/%1/%2_bedrooms/price_%3-%4/town_%5/development_%6/? [R,L]
It assumes you put .htaccess in server root and that there is a file search.php in root too.
Original:
I think you can use PT and QSA Rewrite Rule flags (http://httpd.apache.org/docs/current/rewrite/flags.html) in your first rule
Use PT for server-side redirection (it will not change the URL for the user/browser, but will for your server-side scripts)
Use QSA if you wanna carry the query while doing this redirection
You can redirect all requests that don't target an existing file to a specific php-script, for example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [PT,QSA]

Categories