Forum Moderators: phranque

Message Too Old, No Replies

Rewrite Rule Order - Can This Be Done?

Rewriting Twice

         

ambition

11:04 pm on Jan 3, 2007 (gmt 0)

10+ Year Member



Hello,

I am working on a site that uses url redirection like this:

RewriteRule ^stuff/([0-9]*)/?$ /stuff.php?id=$1 [QSA]

However, I accidentally let a few urls get indexed as /stuff.php?id=$1. Is there a way I can redirect those twice? Here is how I am trying to do it:

RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^stuff.php$ [domain.com...] [R=301]
RewriteRule ^stuff/([0-9]*)/?$ /stuff.php?id=$1 [QSA]

Of course that isn't working, or I wouldn't be posting this :). My end goal is to have all of the urls indexed be [domain.com...] Any ideas?

ambition

jdMorgan

12:34 am on Jan 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Do you mean that you literally have a URL exactly equal (or equivalent) to "/stuff.php?id=$1" indexed -- That is, there is a literal dollar sign in the indexed URL's query string?

If so, you'll need to include that "$" in the RewriteCond pattern, and you'll also need to escape it, since otherwise mod_rewrite will try to treat it as a (malformed) back-reference to an undefined variable called "$[".

If you just meant that you have accidentally allowed dynamic URLs like "/stuff.php?id=99" to be indexed, when what you wanted indexed was only the static-looking "/stuff/99" URLs, then disregard that, and remove the "\$" in the example below.

Since your two rules are logically complementary, each undoing the action of the other, you'll need to take explicit steps to prevent an 'infinite' rewrite loop. The easiest way to do this is to allow the redirect rule to act only on original client (browser or robot) requests for the wrong-form dynamic URL, and not for that same URL occurring as a result of the second rule's action. To do this, check %{THE_REQUEST}, which is the entire original client request, like this:

GET /stuff.php?id=99 HTTP/1.1

The whole process is covered in some depth in [/url=http://www.webmasterworld.com/forum92/6079.htm]this thread[/url] in our library [webmasterworld.com].

Along with some other tweaks, the resulting code should look something like this:


RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /stuff\.php\?id[b]=\$([/b][0-9]+)\ HTTP/
RewriteRule ^stuff\.php$ http://www.example.com/stuff/%[b]1?[/b] [R=301,L]
#
RewriteRule ^stuff/([0-9]+)/?$ /stuff.php?id=$1 [QSA,L]

Also, [QSA] in the last rule is only needed if requests for URLs such as example.com/stuff/99?some_name=some_value are valid and expected, and that query data must be passed through to stuff.php along with "id=99". If this is not the case, omit the "QSA" and use only [L].

Jim

ambition

1:30 am on Jan 4, 2007 (gmt 0)

10+ Year Member



Jim,

Once again you answer my question in no time flat. The 2nd case you suggested is correct, I had dynamic urls indexed, not literal dollar signs. I was able to use your suggestions to get it working, and thanks for the extra information about the [QSA]. You have answered several questions of mine on this forum, and it is very much appreciated.

ambition