Pretty Urls (htaccess file?)

Let me just check that I understand what you’re saying… basically you can generate a link OK, which looks something like this /products/12345/my-product-name, but if you navigate to that URL in your browser, the product ID is not being passed to your script via $_GET[‘product_id’], is that the problem?

Hi,

Yes that it is right.

I cant add the linkname to the link without it interfering with the query.

I managed to recreate the problem on my local server, and I managed to solve it by making a couple small changes to the .htaccess file.

First, add this line to the top of the file:

Options -MultiViews

Then browse to the test URL, and you’ll probably get a 404 Not Found error. If you do, you’ll also have to change this line, removing the / in front of products:

RewriteRule ^products/product/([a-zA-Z0-9]+)/(.*)$ products/product.php?product_id=$1 [QSA,L]

Thanks,

I tried but couldn’t get it to work.

This is the code I am using.


<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^ index.php [L]
  RewriteRule ^products/product/([a-zA-Z0-9]+)/(.*)$ products/product.php?product_id=$1 [QSA,L]
</IfModule>

Should I be producing the link like this?

<?php echo $row['linkname'] . '/' . $row['product_id']; ?>

You need to switch your last two rewrite rules around, like this:


RewriteRule ^products/product/([a-zA-Z0-9]+)/(.*)$ products/product.php?product_id=$1 [QSA,L]
RewriteRule ^ index.php [L]

your RewriteRule ^ index.php [L] rule is basically a catchall, and any rules you put after it will never be reached.

Thanks,

I removed the index.php but the link still fails.

The link with just the product_id works. Is it possible to echo something into the link but for it to be ignored from a query?

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^products/product/([a-zA-Z0-9]+)/(.*)$ products/product.php?product_id=$1 [QSA,L]
</IfModule>

It might be easier just to test that the rewrite rule is working and passing the product id by typing in a URL for now. The URL I’ve been using to test on my system is products/product/123/chest-of-drawers-oak, which I’m typing in manually.

From within your products.php, trying doing var_dump($_GET); to see what values (if any) are being passed to your script. Could you also paste the contents of your .htaccess please?

Thanks,

Unfortunately I still cant get this to work. Im not sure what the code should be doing it. Should it be ignoring the $name variable but only count the $product_id

If you could post the code from your .htaccess file, and from your product.php file it would make it easier to try and find the problem.

Hi,

Please see following…

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([a-z]+)/([a-z\\-]+)$ /$1/$2.php [L]

# Disable directory listing from this point
Options -Indexes

# Prevent viewing of htaccess file
<Files ~ "^\\.ht">
order allow,deny
deny from all
satisfy all
</Files>

# Error Pages
ErrorDocument 404 /404-error.php

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^products/product/([a-zA-Z0-9]+)/(.*)$ products/product.php?product_id=$1 [QSA,L]
RewriteRule ^ index.php [L]
</IfModule>

<div id="menulowerlinkscell">
<div class="menulowerlinks">
<a href="/products/nameproductscategorised/pine" rel="nofollow" class='lowermenulink'>Pine Furniture</a>
</div>
<div class="menulowerlinksinner">
<a href="/products/nameproductscategorised/oak" rel="nofollow" class='lowermenulink'>Oak Furniture</a>
</div>
<div class="menulowerlinksinner">
<a href="/products/nameproductscategorised/mahogany" rel="nofollow" class='lowermenulink'>Mahogany Furniture</a>
</div>
<div class="menulowerlinks">
<a href="/products/nameproductscategorised/white" rel="nofollow" class='lowermenulink'>White Furniture</a>
</div>
</div>

<div id="breadcrumbscell">
You Are Here: <a href="/index.php" rel="nofollow"  class='breadcrumbslink'>Home</a> > <?php echo $row ['name'];?>
</div>
<div id="singleproductcell">

<div class="productsborder">

<div class="singleproductimageborder"><a rel="nofollow" href="<?php echo $row['link'];?>" target="_blank"><img src="<?php echo $row['image_link'];?>"  alt="<?php echo $row['name'];?>" /></a></div>




<div class="productrightcell"><div class="singleproductdescriptionborder"><a rel="nofollow" href="<?php echo $row['link'];?>" target="_blank" class='productlink' ><?php echo $row['name'];?></a></div>
<div class="singleproductpricingborder">
Price £<?php echo $row['price'];?> - Save <?php echo $row['discount'];?>%<br /></div><div class="productdescriptionborder"><div class="productdetailsabout">About</div><?php echo (strlen($row['description']) < 1000) ? $row['description'] : trim(substr($row['description'], 0, 1000)) . "..."; ?></div>
<div class="productdescriptionborder"><?php echo (strlen($row['fulldescription']) < 1000) ? $row['fulldescription'] : trim(substr($row['fulldescription'], 0, 1000)) . "..."; ?></div></div>
</div>
</div>
<div class="productclearanceareas">
<div class="productclearanceareastitle">
Clearance Range
</div>
<div class="productclearanceareascell">
<?php

$query = mysql_query("SELECT * FROM productdbase ORDER BY discount DESC LIMIT 3");
while($row = mysql_fetch_array($query)) {
    ?>




<div class="productrangeborder">


<div class="productsdetailsborder"><a href="http://ukhomefurniture.co.uk/products/product/<?php echo $row['product_id']; ?>" class='productlink' ><?php echo $row['name']; ?></a></div>

<div class="productimageborder"><a href="http://ukhomefurniture.co.uk/products/product/<?php echo $row['product_id']; ?>" ><img src="<?php echo $row['image_link']; ?>" alt="<?php echo $row['name']; ?>" /></a></div>






<div class="priceborder">Price &pound;<?php echo $row['price']; ?><br /></div><div class="discountborder">Save <?php echo $row['discount']; ?>%<br /></div></div>


<?php
}

?>
</div>
<div class="productclearancearticles">
<div class="productclearancearticlestitle">
Latest Articles
</div>
<div class="productclearancearticlesticlesborder">

<?php

$query = mysql_query("SELECT * FROM articles ORDER BY ID DESC LIMIT 5");
while($row = mysql_fetch_array($query)) {
    ?>

<div class="productclearanceaarticleslinks"><a href="/articles/article/<?php echo $row['ID']; ?>" class='articleslink' rel="nofollow" ><?php echo $row['title']; ?></a> | <a href="/articles/articlesfiltered/<?php echo $row['articlecategory']; ?>" rel="nofollow"  class='articlesfilterlink'><?php echo $row['articlecategory']; ?></a></div>

<?php
}

?>

</div>
</div>
</div>
</div>
</div>

OK, so your .htaccess file needed some changes to get it working on my machine. Here’s what I did:


Options -Indexes
Options -MultiViews
Options +FollowSymLinks

# Prevent viewing of htaccess file
<Files ~ "^\\.ht">
order allow,deny
deny from all
satisfy all
</Files>

# Error Pages
ErrorDocument 404 /404-error.php

# Rewrite Rules
<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^([a-z]+)/([a-z\\-]+)$ /$1/$2.php [QSA,L]
  RewriteRule ^products/product/([0-9]+)/(.*)$ products/product.php?product_id=$1 [QSA,L]
</IfModule>

As for the php code you shared, I couldn’t see any code there for retrieving the product ID from $_GET?

Cheers mate,

This is the get code…

<?php
if (isset($_GET['product_id']))
$product_id = mysql_real_escape_string($_GET['product_id']);
$sql = "SELECT * FROM productdbase WHERE product_id = '$product_id'";
$res = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_assoc($res); // no need to loop since you are retrieving only one row
$num_rows = mysql_num_rows($res); // check to see if any results were found, just in case someone puts an ID in the url without clicking on your link
?>

That looks like it should work OK in combination with the changes to your .htaccess file.

Hi,

I did change the htaccess file but it doesn’t work.

Should I be using the product_id first. I did try that but it still doesn’t work.

Not sure what you mean?

Can you try putting var_dump($_GET); at the top of your product.php file and see what you get?

Hi,

The vardump produces this

array(1) { [“product_id”]=> string(4) “6550” }

Sorry, should my link be .com/red-widget/12345 or .com/12345/red-widget

That’s good, so the rewrite rule is passing through the value to your script OK. One thing I did notice about your PHP code is that you’re missing the braces from your IF statement. Try this and see what it gives you:


if ($product_id = filter_input(INPUT_GET, 'product_id', FILTER_SANITIZE_NUMBER_INT)) {
    $sql = "SELECT * FROM productdbase WHERE product_id = $product_id";
    $res = mysql_query($sql) or die(mysql_error());
    $row = mysql_fetch_assoc($res); // no need to loop since you are retrieving only one row
    var_dump($row);
}

Note that I’ve used filter_input to get and filter the value from $_GET, making sure that only an integer (whole number) can be passed into the script.

With the current rewrite rule, your URLs should be in the format example.com/products/product/12345/red-widget

Hi,

Still no luck with that Im afraid. Many thanks for your help so far.

What part of this code blocks the name of the product from being read?

 RewriteRule ^products/product/([0-9]+)/(.*)$ products/product.php?product_id=$1 [QSA,L]

What response did you get from the var_dump of the db result? Because from the information you’ve provided, the problem is related to pulling the correct info out of the DB. As I stated before, the rewrite rule looks to be working properly, as you can see from the results of doing var_dump($_GET).

It doesn’t block it, it just doesn’t pass it to the script. This part ([0-9]+) captures the product id number, which is then passed to your script as the value of product_id, by this part product_id=$1 (The $1 signifies the first match, in this case the product id - the product name would be $2)

Hi,

The vardump displays everything from the database for this pirticular item.