homepage Welcome to WebmasterWorld Guest from
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

redirect by using .htaccess
trying to redirect dynamic page to static url by htaccess

 5:29 am on May 21, 2012 (gmt 0)


im trying to redirect my old url Example.com/gases.php?cid=1&gases=nitrogen to Example.com/gases/nitrogen.php

for this im using the redirect in htaccess which is

Redirect 301 /gases.php?cid=1&gases=nitrogen http://www.example.com/gases/nitrogen.php

but this redirect is not working,

pls suggest



 7:12 am on May 21, 2012 (gmt 0)

Quick answer: Can't do it in mod_alias ("Redirect" by that name). You need to change over to mod_rewrite and include a RewriteCond looking at the query string. Search this forum and you will find a long detailed explanation of how it works. Also several thousand examples ;)


 12:27 pm on May 21, 2012 (gmt 0)

Hi Lucy,

Thanks for your response, but im quiet new so will you pls help me by making a code for me and ill put it on my .htaccess file


 6:44 pm on May 21, 2012 (gmt 0)

The code has already been made and posted in at least 3000 previous threads in this forum. Lucy could cut and paste one of those answers here tomorrow or when she next has some free time, or you could read the information right now without having to wait.


 7:00 pm on May 21, 2012 (gmt 0)

mod_alias's RedirectMatch would work.


 7:08 pm on May 21, 2012 (gmt 0)

As it needs to look at the QUERY_STRING, no it would not.

This is a job for a RewriteRule with a preceding RewriteCond.


 7:27 pm on May 21, 2012 (gmt 0)

mod_alias's RedirectMatch would work.

Might you have a simple example of this implementation?


 8:34 pm on May 21, 2012 (gmt 0)

ok.. this is what I have so far.. I got most of the issues worked out, but the metacharacter thing is driving me nuts.

my .htaccess

# This strips the /?/ from the url
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/([\?]{1})/(.*)
RewriteRule $1$2 $2 [R=301,L]
RewriteEngine Off

But yet.. It's not working. Tested it using a PCRE regex tester and it should work, but it's now. What am I doing wrong?


 9:15 pm on May 21, 2012 (gmt 0)

Where are $1 and $2 being populated from?

You have no "captures" in your rule. $1 and $2 can appear only in the rule target, not in the pattern part.

RewriteBase / is the default and can be omitted.

RewriteRule should be looking for gases.php and the preceding RewriteCond should be testing QUERY_STRING or THE_REQUEST for cid=1 and gases=nitrogen.

RewriteRule target URL should contain protocol and domain name.

 9:27 pm on May 21, 2012 (gmt 0)

ok.. I'm still working on this after 2 weeks.. I'll eventually get it.. **sigh**

I'm getting requests for http://example.com/?/post-name and need to omit the "?/" part of the url.. any help would seriously be appreciated.


 11:18 pm on May 21, 2012 (gmt 0)

Do a Forums search for... Oh, never mind, I've got the boilerplate right here and will paste it in.
Query Strings

The Query String, also known as a Parameter, is the part of an url after the question mark. Question = query.

By default, rewrites simply ignore the query string. That is, mod_rewrite stashes the query in a safe place, does its stuff to the part before the question mark, and then reappends the original query.

Changing a Query

#1 To delete a query, add a ? to the end of your rewrite target.
#2 To replace a query—or create a new one—add ?blahblah to the rewrite target. The blahblah can be either literal text, or stuff you captured earlier. (#1 and #2 are really the same thing: you're just replacing the query with either something or nothing.)
#3 To add to an existing query, again put ?blahblah at the end of the target, but also add [QSA] to your flags (the bracketed items at the end of the Rule). It stands for "Query String Append", meaning that the blahblah is to be added to the existing query—if any—instead of replacing it.

Getting the Query

You only need to retrieve the original query if
#1 you want the rewrite to behave differently depending on what the query was
#2 you need to change or delete the query

Add a Condition that says

RewriteCond %{QUERY_STRING} blahblah

using your ordinary Regular Expressions, anchors and ! as needed.

To test whether there was a query at all

RewriteCond %{QUERY_STRING} .

which simply means "If the query contains at least one character of any kind".

If you need to capture any of the query, use parentheses as usual. In the rewrite target, the captures will be %1, %2 etc instead of $1, $2 etc, because they are coming from a Condition instead of the Rule. Each set is separately numbered, so the first capture from the Rule will still be $1.


 9:42 pm on May 22, 2012 (gmt 0)


I can't seem to get it working. I'm interested in finding out what is stored in the QUERY_STRING. Is there a quick and dirty way to do it?

It just seems like the Rewrite is not removing the "?" from the url. It's causing me tons of 404s. It just started recently. I think the problem is on Google's end, but good luck trying to get them to answer the question. It would be easier to fix via this if I can get it working.

Any ideas on how to eliminate that /?/ from the URL?

example url: http://example.com/?/post-name should be http://example.com/postname

TIA. If you or anyone would like to come up with a solution for me that works, I'd be happy to donate or pay.


 11:04 pm on May 22, 2012 (gmt 0)

I'd be happy if I could just pass the URL to a bash script and do the rewrite there, then pass back to mod_rewrite.

That information also seems to be sparse. If only someone could come up with a mod_sed module that actually allows URL rewriting without using the PCRE regexp format, it would be a much more elegant solution.


 11:11 pm on May 22, 2012 (gmt 0)

PCRE allows for very compact and concise code that runs ultra efficiently. Anything you replace it with will usually be much less efficient.

That said, if I have a particular task that can be performed using PHP and the URL set is easy to discern, I'll internally rewrite those requests to a script for further handling.

Your particular problem first needs you to start by changing the links on the page to point to the URLs that you want users to see and use. URLs are defined in links. You'll then need an internal rewrite. This will connect requests generated after the link is clicked to the internal filepath that will handle that request. Separately you'll also need a redirect from the old URL format to the new format. Both of those things will each use a RewriteRule.


 11:30 pm on May 22, 2012 (gmt 0)

Whoops! Overlapped previous three posts thanks to typing slow.

I can't seem to get it working. I'm interested in finding out what is stored in the QUERY_STRING. Is there a quick and dirty way to do it?

If you comment-out the part of your Rewrite that is meant to deal with the Query, and then follow the link, your browser's address bar should show the whole thing, query and all.

It just seems like the Rewrite is not removing the "?" from the url.
#1 To delete a query, add a ? to the end of your rewrite target.

To you and me the ? looks like part of the URL. But to your server, everything starting with ? is a query. So you need to capture it-- minus the leading / slash-- and then stick it back onto the end of the URL.

And yes, if you can get gwt to drop a hint where it's getting those spurious queries, that would be a big help. Or possibly no help at all, if it's one of those URLs that exist only in google's fevered imagination. There have been several recent threads about g### following links that were never meant to be links.


 11:35 pm on May 22, 2012 (gmt 0)

You can always install a logging script and you'll soon discern where the requests are coming from:

$statusCode to a three digit number before calling the include file when calling it from your error document pages.


# Error Event Logging 2012-05-24 (logger.php)

$oldSetting= ignore_user_abort( TRUE );// otherwise can screw-up logfile

if( !empty( $GLOBALS[ '_SERVER' ])) {
} elseif( !empty( $GLOBALS[ 'HTTP_SERVER_VARS' ])) {
} else {

$requestHost= ${$_SERVER_ARRAY}[ 'SERVER_NAME' ];

if(stristr($requestHost, 'example.co.uk')) {
if(stristr($requestHost, 'dev')) {
define( '_DIRECTORY', '/var/www/vhosts/example.co.uk/subdomains/dev/httpdocs/includes/logfiles/' );
$site = 'dev';
} else if(stristr($requestHost, 'www')) {
define( '_DIRECTORY', '/var/www/vhosts/example.co.uk/httpdocs/includes/logfiles/' );
$site = 'www';
} else if(!stristr($requestHost, 'dev') && !stristr($requestHost, 'www')) {
define( '_DIRECTORY', '/var/www/vhosts/example.co.uk/httpdocs/includes/logfiles/' );
$site = 'www';

define( '_LOGFILE','errorlog' . date('-Y-m-') . $site . '-' . $statusCode . '.txt' );
#define( '_LOGFILE','errorlog' . date('-Y-m-') . $site . '.txt' ); // all in one
define( '_LOGMAXLINES','3000' );

global ${$_SERVER_ARRAY};


$datetime= date( 'Y-m-d H:i:s O' );

$remoteIP= ${$_SERVER_ARRAY}[ 'REMOTE_ADDR' ];

$requestURI= ${$_SERVER_ARRAY}[ 'REQUEST_URI' ];

$referer= ( isset( ${$_SERVER_ARRAY}[ 'HTTP_REFERER' ]))
: '<unknown referer>';

$userAgent= ( isset( ${$_SERVER_ARRAY}[ 'HTTP_USER_AGENT' ]))
: '<unknown user agent>';

if(preg_match('#(Opera\ [0-9]+\.[0-9]+)#',trim($userAgent), $extracted)) {
$agent = $extracted[1];
} elseif(preg_match('#^(Opera[^(\ ]+)#',trim($userAgent), $extracted)) {
$agent = $extracted[1];
} elseif(preg_match('#^(Xenu.*)#',trim($userAgent), $extracted)) {
$agent = $extracted[1];
} elseif(preg_match('#compatible;\ ([^;]+)#',$userAgent, $extracted)) {
$agent = $extracted[1];
} elseif(preg_match('#^([^\ ]+\ )+([^\(\)]+)#',trim($userAgent), $extracted)) {
$agent = $extracted[2];
} else {
$agent = '<see notes>';

$remoteIP= str_pad($remoteIP, 15);

$agent= str_pad($agent, 22);

$requestHost= str_pad($requestHost, 26, " ", STR_PAD_LEFT);

$requestURI= str_pad($requestURI, 80);

$referer= str_pad($referer, 110);

$userAgent= str_pad($userAgent, 120);

$logLine= $datetime . " - " . $remoteIP . " - " . $agent . " - ". $statusCode . " - ". $requestHost . " - ". $requestURI . " - ". $referer . " - ". $userAgent . "\n";

$log= file( $logFile );// flock() disabled in some kernels (eg 2.4)

if( $fp = fopen( $logFile, 'a' )) {// tiny danger of 2 threads interfering; live with it
if( count( $log ) >= _LOGMAXLINES ) {// otherwise grows like Topsy
fclose( $fp );// fopen,fclose put close together as possible
while( count( $log ) >= _LOGMAXLINES ) array_shift( $log );
array_push( $log, $logLine );
$logLine= implode( '', $log );
$fp= fopen( $logFile, 'w' );
fputs( $fp, $logLine );
fclose( $fp );

ignore_user_abort( $oldSetting );



 2:07 am on May 23, 2012 (gmt 0)


I'm not a php coder, but rather a sys-admin type. I would have no idea where to put this php script in a wordpress install.

I've been trying to figure out the google thing, but all the URLs are definitely coming from google. The funny thing is I look at the sitemap I submit to them and even had it validated by multiple sitemap validators (including google's).

This is what I have in my .htaccess file for this rule.. am I missing something?

RewriteEngine On
RewriteCond %{QUERY_STRING} ^/(.*)?$ [NC]
RewriteRule ^/$ $1 [QSA,L]


 2:20 am on May 23, 2012 (gmt 0)

ok.. I've gotten a little further.. but I'm not sure what to do to eliminate the ?/iphone. I'm not doing this on the apache server itself, but using the .htaccess tester at: [htaccess.madewithlove.be...]

I put in http://example.com/?/iphone

these are the rules I put in:

RewriteCond %{QUERY_STRING} ^/(.*)$ [NC]
RewriteRule ^(.*) %1 [QSA,L]

and this is the resulting url I get: http://example.com/iphone?/iphone

So what am I doing wrong?


 2:21 am on May 23, 2012 (gmt 0)

Your rule can never run, because ^/$ can never match any real request, other than for example.com// with two slashes. Your rule also performs an internal rewrite and not the required external redirect. $1 is always blank because you haven't captured anything. In short the rule does nothing at all.

As for where you'd put the PHP code. It goes in a separate file. You then "include" that file at the bottom of the page you want to track, and set the $statusCode variable just before you do so. Inside the included file you also have to set the server paths that will be used.


 2:26 am on May 23, 2012 (gmt 0)


I've gotten a bit further, I guess we cross posted.. see my second rewrite rule response.


 2:52 am on May 23, 2012 (gmt 0)

Well.. looks like I fixed it.. Turns out the htaccess tester wasn't that accurate.

The final solution was:

# This strips the /?/ from the url
RewriteBase /
RewriteCond %{QUERY_STRING} ^/(.*)$ [NC]
RewriteRule ^(.*) %1? [R=301,L]

Thanks for all your help. :) You two are AWESOME..


 2:54 am on May 23, 2012 (gmt 0)

by the way.. I'll be posting on my blog.. [swimminginthought.com...] all about you two! :) Hope you don't mind me giving you two kudos. I get >1200 unique visitors a day (and growing) and you two were the only helpful ones.. so may I have permission to sing the praises of both of you? I won't do it without your permission.


 5:12 am on May 23, 2012 (gmt 0)

Hi and thanks to all...

finally with the help of information from boilerplate and other feedback's I'm able to write my code.

Finally, the code I'm using is:

RewriteCond %{QUERY_STRING} ^cid=9&gases=nitrogen$
RewriteRule ^purity\.php$ http://example.com/gases/nitrogen.php? [R=301,L]

but, im not able to go EXTENSIONLESS.

pls let me know how to do that.


 7:32 am on May 23, 2012 (gmt 0)

RewriteRule ^(.*) %1 [QSA,L]

and this is the resulting url I get: http://example.com/iphone?/iphone

So what am I doing wrong?

Guess you figured it out ;)

but, im not able to go EXTENSIONLESS

For that, you have to add a step: Rewrite (not Redirect) from the extensionless url to the real location of the text. It can be as simple as

RewriteRule ^([a-z]+)$ /$1.html [L]

or as complicated as

RewriteRule ^([a-z]+)/([a-z]+)/([a-z]+)$ /index.php?$1&$2&$3 [L]

Those are not real Rules! I'm just illustrating the range of possibilities.

Now, how did this thread get to have two entirely different questions and askers mixed into it?

Global Options:
 top home search open messages active posts  

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved