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.

  • You could also avoid duplicates by setting the canonical link element in the head section.
    – MrWhite
    Commented Feb 20, 2014 at 19:33

4 Answers 4


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);

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


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


Change to this ( "NC" you can remove )

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

.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);

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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