Forum Moderators: phranque

Message Too Old, No Replies

RewriteRule 301 redirect

RewriteRule 301 redirect new to php and using phpbb forum.

         

BrainDed

3:58 pm on May 19, 2011 (gmt 0)

10+ Year Member



Moved topic from [webmasterworld.com...]

I I changed my URL structure for a message board I run and am seeking assistance on creating a 301 redirect. My site runs joomla, phpbb3 board. I have very limited experience with php and am struggling.

Here is what I am working with"

Structure was /messageboard/(forum number)/(topic number)
Strucure is messageboard/(forum NAME)/(topic NAME)

http://www.example.com/messageboard/16/16417.html

http://www.example.com/messageboard/mlb/astros-have-no-chance-in-winning-the-central-16417.html



The topic # is converted on the fly so I think I just need to redirect the subdirectory or forum name. I tried this below, but had no success, even with static pages.

redirect 301 /messageboard/(forum number)http://www.example.com/messageboard/(forum NAME)


I tried searching for mod_rewrite examples to edit and use but with my lack of knowledge it is a bit overwhelming. Here is my current htaccess file and domain if you want to look. Thanks in advance for any help!

domain = brewerscubs

#
# Uncomment the statement below if you want to make use of
# HTTP authentication and it does not already work.
# This could be required if you are for example using PHP via Apache CGI.
#
#<IfModule mod_rewrite.c>
#RewriteEngine on
#RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
#</IfModule>

<Files "config.php">
Order Allow,Deny
Deny from All
</Files>

<Files "common.php">
Order Allow,Deny
Deny from All
</Files>

Samizdata

5:22 pm on May 19, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I think I just need to redirect the subdirectory or forum name

If that were the case then something like this should work:

RedirectMatch 301 ^/messageboard/number/(.+)$ http://www.example.com/messageboard/name/$1

Unfortunately there appears to be more to it as you also seem to be changing the file names.

As the file names will all be unique there is no pattern to match, and redirecting them all individually is probably too much work.

A real expert may have more to offer you.

...

BrainDed

5:40 pm on May 19, 2011 (gmt 0)

10+ Year Member



Tried that and did not see any change in behavior.. Two things.

1 - I removed the # sign in front of engine on. Is anything else needed?

2 - I'm willing to pay a "real expert," any suggestions?

Samizdata

5:51 pm on May 19, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I removed the # sign in front of engine on. Is anything else needed?

The Rewrite Engine is not required in this case.

The .htaccess file overrides (where allowed) the Apache configuration and is extremely powerful - one character out of place can take your site offline. Beginners should approach it with extreme caution.

As for experts, the best I have ever come across post in this forum.

They may, however, say "I wouldn't start from here".

...

g1smd

7:48 am on May 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Since mod_rewrite has no way of knowing the new names that need to be assigned, the best solution is to internally rewrite all requests for old URLs to a special script which then looks up in the database what the new URL will be. It then sends the 301 header and the location header with the new URL details.

If all the old URLs look like:
/messageboard/16/16417.html
then the internal rewrite part is very simple.

RewriteRule ^messageboard/([0-9]+)/([0-9]+)\.html /my-special-script.php?a=$1&b=$2 [L]


The two numbers will be available to your PHP script as $GET[$a] and $GET[$b] or similar (look in the manual for the exact syntax). The PHP script reads the database to ascertain the "words" to be placed in the URL and then sends the headers.

If you can't do the database read, consider using a similar PHP script but with the data in a PHP array or in a CSV file. This will make it easier to maintain, rather than writing out hundreds of rules in the .htaccess file.

The really long-winded way would be to list all the rules manually in .htaccess. That's too error prone. Note too, that with any manual method you might struggle to keep up to date as you will need to edit your list every time you add or remove pages from the site.

One final word. If you use RewriteRule for any of your rules you must use it for all of your rules. That is, don't mix Redirect and RedirectMatch (used my mod_alias) with RewriteRule (used by mod_rewrite) in the same site. The .htaccess file is parsed in "per-module" order, and you cannot guarantee the order of rule processing. It should be that mod_alias runs before mod_rewrite when processing a request, but if the reverse occurs you can end up with some very tricky hard-to-diagnose problems.

lucy24

10:10 am on May 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Would a Rewrite Map [httpd.apache.org] work? It looks pretty alarming but also looks as if it would be ideal in some situations.

g1smd

1:06 pm on May 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You could also use RewriteMap I think. Can't help you with much to do with it though, as I have never used it myself.

However you do it, you'll need a database or array lookup to "translate" the URLs.

BrainDed

3:52 pm on May 23, 2011 (gmt 0)

10+ Year Member



Thanks for the help.. I was able to find someone with the know how and paid them to do as you suggested.


Here it is in case someone stumbles on this thread with a similar problem.

1 - Added this to htaccess

RewriteRule ^messageboard/([0-9]+)/([0-9]+).html$ redirect.php?fid=$1&tid=$2


######################

2 - Created a php file named redirect.

<?php


// database connection setup
$dbhost = "xx";

$dbuser = "#*$!";

$dbpass = "#*$!";

$dbname = "xx";


mysql_connect($dbhost, $dbuser, $dbpass) or die('Error: ' . mysql_error());

mysql_select_db($dbname) or die(mysql_error());


// retrieves the topic id and forum id sent from the htaccess script
$topic_id = $_GET['tid'];
$forum_id = $_GET['fid'];


// sql query to get the topic title
$sql = 'SELECT topic_title AS topic_title
FROM phpbb_topics
WHERE topic_id = '.$topic_id.'';
$result = mysql_query($sql);
$data = mysql_fetch_assoc($result);

$title = $data['topic_title'];


// sql query to get the forum name
$sql = 'SELECT forum_name AS forum_name
FROM phpbb_forums
WHERE forum_id = '.$forum_id.'';
$result = mysql_query($sql);
$data = mysql_fetch_assoc($result);

$name = $data['forum_name'];

// formatting to strip the string from weird characters and add hyphens
$name = strtolower($name);
$name = str_replace(" ", "-", $name);
$name = ereg_replace("[^A-Za-z0-9-]", "", $name );


$title = strtolower($title);
$title = str_replace(" ", "-", $title);
$title = ereg_replace("[^A-Za-z0-9-]", "", $title );

// php redirect to new file name
header( 'Location:/messageboard/'.$name.'/'.$title.'-'.$topic_id.'.html');


?>

g1smd

6:35 pm on May 23, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You now have a 302 redirect.

You need a 301 redirect. Add another HEADER before the one shown in your script.

Additionally, the "location" must be a fully qualified URL with protocol and domain name included.

See also: [webmasterworld.com...]

BrainDed

6:53 pm on May 23, 2011 (gmt 0)

10+ Year Member



Thanks g1smd..

I'm completly confused though :)

I read over that thread and I think I should add this before my rewrite rule?

"RewriteCond %{QUERY_STRING} (^|&)products_id=([0-9]+)(&|$)"

What goes in place of Products?

Sorry, I am complete noob, can you spell it out for like you would to a child..lol?

g1smd

7:13 pm on May 23, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You only need a line testing QUERY_STRING if the old URLs on your site used a query string.

Your script needs modifications to send the 404 header if the requested URL was invalid.

You need to alter your current 302 response to instead be a 301 redirect. The target URL needs the protocol and domain name, not just the path.

BrainDed

8:31 pm on May 23, 2011 (gmt 0)

10+ Year Member



So i just need to change this part of my php file?

// php redirect to new file name
header( 'Location:/messageboard/'.$name.'/'.$title.'-'.$topic_id.'.html');


to

// php redirect to new file name
header( 'Location:http:www.example.com/messageboard/'.$name.'/'.$title.'-'.$topic_id.'.html');



######

And what should the other header be in htaccess?

g1smd

9:56 pm on May 23, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You need a space after "Location: "

The http: needs two // making http://

The other header is the one with "301" in it.

BrainDed

11:39 pm on May 23, 2011 (gmt 0)

10+ Year Member



I think I got it... like this, at the end of the redirect script. correct?

// php redirect to new file name
Header( "HTTP/1.1 301 Moved Permanently" );
header( 'Location: http://www.example.com/messageboard/'.$name.'/'.$title.'-'.$topic_id.'.html');

g1smd

12:05 am on May 24, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



That looks OK. Test it.

Test it with valid URLs and make sure it takes you to the right place.

Test it with non-valid URLs and hope you get the correct 404 error.

BrainDed

12:18 am on May 24, 2011 (gmt 0)

10+ Year Member



It does not produce any 404 error, just redirects..

www.brewerscubs.com/messageboard/5/6216.html?start=20