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

Apache Web Server Forum

301 Redirect with Path Arguments to None
Old URLs had arguments, new ones do not

 7:28 pm on May 31, 2008 (gmt 0)

I'm trying to get a site moved from one server to another, and I cannot get the 301 redirects working at all.

I need to go from this: www.domain.dom/blog-archive.php?page=20080531-road-trip

to this: www.www.domain.dom/2008/05/31/road-trip/

I've tried several methods (found in different Google searches) but they all result in a 404 page not found error. The destination page does show up fine if I enter the URL directly. And, to test that the redirect otherwise working, I tried a page (that doesn't exist) without any path arguments, and the redirection worked just fine:

Redirect 301 /test.php [domain.dom...]

This is what I've been (most recently) using to try to redirect the page with path arguments:

Redirect 301 /blog-archive.php?page=20080531-road-trip [domain.dom...]

I've tried escaping different characters to no avail.

Any ideas on how to get this to work?



 9:34 pm on May 31, 2008 (gmt 0)

You can't do it with mod_alias. Use mod_rewrite, use a RewriteCond to examine THE_REQUEST, and then append a "?" to the substitution URL to clear the incoming query string.

However, this is the third of three steps, and you haven't mentioned the first two (and more-important) steps at all.

See this thread [webmasterworld.com] for details.



 9:45 pm on May 31, 2008 (gmt 0)

Huh? First two steps? I'm just trying to do a redirect as I've moved from one server to another.

The old server used this structure for URLs:


The new server uses this URL for the new page with the same content:


I'm unclear what rewriting would do, as "www.domain.dom/blog-archive.php?page=20080531-road-trip" doesn't exist at all on the new server.


 9:51 pm on May 31, 2008 (gmt 0)

Very well, then use mod_rewrite, and a RewriteCond to examine the query string. Append a "?" to the substitution URL to clear this incoming query string, after back-referencing the values you need in the substitution URL.

Using this method, it appears that only a single RewriteRule will be needed.

[added] If you are not changing domain names, then I recommend that you read and understand that cited thread carefully before rushing off to make a change. It is likely that the method in that thread is exactly what you need to do, and if you simply do a redirect (as described here in this thread), you'll have trouble.

You say "the new server uses URLs like this," but in fact, the server doesn't care what the URL is. If you use the wrong method, then the SEF plug-in code that you very likely have on that new server and your redirect will likely interfere with each other, causing an "infinite" rewrite/redirect loop. And in that case, the method in the cited thread is precisely what you need to fix the problem. The SEF plug-in would be "step 2" in the cited thread.[/added]


[edited by: jdMorgan at 10:00 pm (utc) on May 31, 2008]


 10:38 pm on May 31, 2008 (gmt 0)

Thanks, but I'm just not seeing where any of that really helps me. The path arguments from the old server aren't anything that I can convert into the new URL structure on the new server.

For example, in the URL "blog-archive.php?page=20080531-road-trip" the path argument for the page variable is "20080531-road-trip" which I cannot break down. (I'm sure there's probably a way to break that down somehow, but still the final bit, the "road-trip" part may not necessarily associate with the text for the new URL structure.)

In this example, the new URL is "http://www.domain.dom/2008/05/31/road-trip/" but that's just in this case. In another URL, the path argument may have been something like "20080530-new-rental" and the new URL might be something like "http://www.domain.dom/2008/05/30/new-rental-car/" or even something where the text doesn't associate at all.

So, as I see it, I cannot do a rewrite rule that changes one pattern to another because there isn't necessarily a pattern that can be extracted from the old path arguments.

I think that I would need some way of hardcoding each URL to redirect to the new URL.

Here is what my .htaccess file looks like without any of the aforementioned attempts at redirection:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.domain.dom$
RewriteRule ^(.*)$ [domain.dom...] [R=301]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]


 10:55 pm on May 31, 2008 (gmt 0)

Ah... You did not say anything about changing the file structure, you said you were changing servers.

You can use the "examine QUERY_STRING" method then.

Put individual rules for the old URLs that "don't associate" first, then follow with a generic (e.g. "new-rental-car" rules first, a generic to map "road-trip" and other directly-associatable URLs)

Where that thread may help you is in demonstrating regex pattern and back-reference usage for the directly-associatable URLs.

If you have a ton of individual rules, there's a trick you can use to make the code 50% more compact. That's details, though, and can wait until you get a few basic rules working.



 11:30 pm on May 31, 2008 (gmt 0)

Got it!

RewriteCond %{query_string} ^page=20080531-car-ride$
RewriteRule ^blog-archive\.php$ [domain.dom...] [R=301,L]



 1:31 am on Jun 1, 2008 (gmt 0)

Yes, but in general, don't take ANY liberties with capitalization, spelling, spacing, or punctuation, compared to the documentation. We've seen evidence of 'picky servers' here in this forum.

Here's what the whole pile should look like, with various corrections/clean-ups:

# Specific redirect
RewriteCond %{QUERY_STRING} ^page=20080531-car-ride$
RewriteRule ^blog-archive\.php$ http://www.example.com/2008/05/31/road-trip/? [R=301,L]
# Catch-all at the end for directly-associated URLs
# (e.g. blog-archive.php?page=20080531-road-trip -> /2008/05/31/road-trip/)
RewriteCond %{QUERY_STRING} ^page=([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^blog-archive\.php$ http://www.example.com/%1/%2/%3/%4/? [R=301,L]
# Redirect any other non-canonical requests to canonical domain
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
# WP internal rewrite code
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Again, if you have more than a dozen "specific URL" redirects, let me know. There's a trick to save some code, but it's difficult to read and write -- and kind of ugly. If you have hundreds of redirects, and have access to httpd.conf, then a RewriteMap would be even better.



 3:40 am on Jun 1, 2008 (gmt 0)


I have about a dozen of two different sets of pages. The first set is on the blog-archive.php page and the other is on a page.php page. With that second set, the path argument value begins with a letter, as in a20080531-title-text. So, for those, would I do something like this:

RewriteCond %{QUERY_STRING} ^page=([a-z]{1})([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]


 3:47 am on Jun 1, 2008 (gmt 0)

Actually, on both blog-archive.php and page.php, I have mixed path arguments. Some have the letter in front; some don't.

Am I right that I would need to do:

RewriteCond %{QUERY_STRING} ^page=([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%1/%2/%3/%4/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page=([a-z]{1})([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

RewriteCond %{QUERY_STRING} ^page=([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^blog-archive\.php$ http://www.example.com/%1/%2/%3/%4/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page=([a-z]{1})([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^blog-archive\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]


 3:36 pm on Jun 1, 2008 (gmt 0)

If you intend to "discard" the prepended letter, then only one rule per "set" would be required. Example of the first two rules in your immediately-previous post compressed to one rule:

RewriteCond %{QUERY_STRING} ^page=[b]([a-z])?[/b]([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

BTW, "[a-z]{1}" is redundant, I just replaced it with "[a-z]", which matches one character by default.

Also, if "blog_archive.php" and "page.php" are now to be redirected to the same static URL-set, then you can combine all four rules above into one:

RewriteCond %{QUERY_STRING} ^page=([a-z])?([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^(blog_archiveŠpage)\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

Replace the broken pipe "Š" character with a solid pipe character from your keyboard before use; Posting on this forum modifies the pipe characters.



 5:39 pm on Jun 1, 2008 (gmt 0)

Thanks much!

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