Take the 2-minute tour ×
Webmasters Stack Exchange is a question and answer site for pro webmasters. It's 100% free, no registration required.

The website I am referencing in my question is http://www.bgmenus.com.

I have successfully created clean urls like this for my listings: http://bgmenus.com/five-guys/341

I rewrote those using this: RewriteRule /([^/.]+)/?$ /restaurants.php?id=$1 [L,NC,QSA]

The issue is the old URLs still exist and work: http://bgmenus.com/restaurants.php?id=341

My question is how can I 301 the /restaurants.php?id=123 version of the URL back to the clean version so there aren't any duplicates.

Thanks for your help.

share|improve this question

migrated from stackoverflow.com Feb 20 at 17:51

This question came from our site for professional and enthusiast programmers.

    
You could also avoid duplicates by setting the canonical link element in the head section. –  w3d Feb 20 at 19:33

4 Answers 4

up vote 4 down vote accepted

You could check the $_SERVER['REQUEST_URI'] on the php script restaurants.php if the request url is the correct. For example:

if ($_SERVER['REQUEST_URI'] !== '/' . $name . '/' . $id)
{
    header ('HTTP/1.1 301 Moved Permanently');
    header ('Location: http://www.bgmenus.com/' . $name . '/' . $id);
    die();
}

Where $name is the restaurant name [five-guys] and $id is the restaurant id [341]

When the hit is from http://bgmenus.com/five-guys/341 the if statement would be false If someones direct hits /restaurants.php?id=123, the if will be true and the user will be redirected to the new seo friendly url

share|improve this answer
    
Worked perfectly. Thanks! –  Trey Copeland Feb 20 at 12:51

You cannot get restaurant name from URL since you only have id. Just based on id you can use this rule above your existing rule:

RewriteCond %{THE_REQUEST} \s/+restaurants\.php\?id=([^\s&]+) [NC]
RewriteRule ^ /restaurant/%1? [R=302,L]

This redirects /restaurants.php?id=123 to /restaurant/123

share|improve this answer

Change to this ( "NC" you can remove )

RewriteRule /([^/.]+)/?$ /restaurants.php?id=$1 [R=301,L,NC,QSA]
share|improve this answer

.htaccess has no way of mapping restaurants.php?id=123 to /five-guys/341; it cannot pull the five guys slug from the database. You need to do this by coding. Here is a rough outline:

// $row variable comes from database
// it might look like
// array("id" => 123, "slug" => "five-guys", "name" => "Five Guys");

$requestedURL = $_SERVER['REQUEST_URI'];
$preferredURL = '/' . $row['slug'] . '/' . $row['id'];

if ($requestedURL !== $preferredURL) {
    header ($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently');
    header ('Location: http://' . $_SERVER['HTTP_HOST'] . $preferredURL);
    die();
}

Depending on your server, the original URL might be logged in another server variable. If you are not sure, so a var_dump($_SERVER) to locate the variable that contains the before-rewriting URL.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.