Friendly URL's - htaccess - mod rewrite problems

Discussion in 'Apache' started by texastez, Apr 18, 2010.

  1. #1
    I would appreciate very much anyone who can help with the following problems I am having with my .htaccess mod_rewrite rules:

    Our site is run using html, php and mysql on shared server at Hostgator using:
    Linux operating system
    MySQL 5.1.30
    Apache version 2.2.15
    php version 5.2.13

    We are running a real estate site where all properties are referenced from the databas as follows (using 555 as property id example):
    http://www.oursite.com/accommodation.php?id=555.

    I am trying to write friendly URL so the property type then id number shows instead.
    For example: http://www.oursite.com/Apartment-555
    Or http://www.oursite.com/Villa-555

    We have property types:
    Apartment
    Villa
    Bungalow
    Finca
    Townhouse
    House
    Studio
    Cottage
    Duplex

    I have achieved this but with problems, here is the .htaccess file:

    SetEnv TZ Europe/London

    Options +FollowSymLinks

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^oursite.com [NC]
    RewriteRule ^(.*)$ http://www.oursite.com/$1 [L,R=301]

    THE ABOVE IS TO MAKE ALL REQUESTS GO TO WWW

    RewriteRule ^Apartment-([0-9]+)_(.*)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^Villa-([0-9]+)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^Bungalow-([0-9]+)_(.*)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^Finca-([0-9]+)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^House-([0-9]+)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^Studio-([0-9]+)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^Cottage-([0-9]+)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^Townhouse-([0-9]+)$ http://www.oursite.com/accommodation.php?id=$1 [P]
    RewriteRule ^Duplex-([0-9]+)$ http://www.oursite.com/accommodation.php?id=$1 [P]

    THE ABOVE ARE WORKING BUT SEE PROBLEMS BELOW

    ErrorDocument 404 /404.shtml

    THE ABOVE IS A CUSTOM 404 PAGE

    All relevant links in all pages have been changed to accomodate the change for example the old links which used to say:
    <a href='accommodation.php?id=".$row["id"]."'> now read...
    <a href='".$row["accommodation_type"]."-".$row["id"]."'>
    And the links work great - showing the friendly URL in the address bar of the browser as: http://www.oursite.com/Apartment-555

    PROBLEM;

    The issue I have is this... If I change the word 'Apartment' to Bungalow or any other property type in the address bar so it reads:
    http://www.oursite.com/Bungalow-555 (it still shows Apartment-555), there isn't a Bungalow-555 in the database so I was sort of expecting a error page!
    And I certainly don't want Google to think there is an Apartment-555 and Bungalow-555 and Villa-555 etc etc.

    I only want whatever is stored in the database to show as a friendly URL

    On another note, I was looking around at other property sites to see if they did the same and came across a site called Holidaylettings.

    Ideally we would like our URL's to behave the same as this site and I have spent the past 7 days reading dozen of sites about Apache, Mod_rewrite and friendly URL's, htaccess and more. I have tried dozen of different conotations but still can't seem to get it right.

    Here is what happens with the holidaylettings site;

    If you take a look at anyone one of the properties they have, for example:
    http://www.holidaylettings.co.uk/rentals/mijas-costa/22122

    If you enter the above URL into your browser and remove any character or several characters from either the word rentals or the word mijas-costa and hit the enter/return key the misspelled jumps back to the original URL above automatically.

    Example:
    http://www.holidaylettings.co.uk/reals/mijas-costa/22122 (couple of letter taken out of the word rentals)
    http://www.holidaylettings.co.uk/rentals/mijsta/22122 (couple letters taken out of mijas-costa)

    but after hitting the enter key on keyboard

    Both incorrect urls jump back to the original;
    http://www.holidaylettings.co.uk/rentals/mijas-costa/22122

    I presume this is done with mod rewrite and .htaccess?
    I would be so grateful if someone could help me on these issues and how to achieve the desired results?
     
    texastez, Apr 18, 2010 IP
  2. fifo

    fifo Peon

    Messages:
    31
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #2
    I am also having problems with mod_rewrite.
    Do you know a good HOW TO guide?
     
    fifo, Apr 18, 2010 IP
  3. showstopper

    showstopper Active Member

    Messages:
    34
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    76
    #3
    sometimes you need to enable mod_rewrite b4 u use it
     
    showstopper, Apr 19, 2010 IP
  4. tolra

    tolra Active Member

    Messages:
    515
    Likes Received:
    36
    Best Answers:
    1
    Trophy Points:
    80
    #4
    The way I would attack this is to route all requests for files/directories that don't exist to your script e.g
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*) accommodation.php
    
    Code (markup):
    Then in accommodation.php parse the request and within the PHP query the property information, now if the type e.g. Apartment matches go on to show the property otherwise output a 404 page or a redirect or something.

    .htaccess has no way of knowing of a property type as it has to read it from the database therefore move all the work to PHP.

    For holidaylettings, it just looks for the id as the last element then if the URL dosn't match what is expected/correct it does a redirect to the corrected version, again it's easy to do once you let PHP do all the work.
     
    tolra, Apr 20, 2010 IP
  5. texastez

    texastez Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Thanks for the info tolra, much appreciated!

    I will try the Rewrite conditions and rule as you suggest.

    I don't suppose you could give me an example of what such code would look like with regards to the holidayletting paragraph or eleborate a little more on this in laymens terms, I am not a php person and only know the very basics

    Any help is much appreciated.
     
    texastez, Apr 24, 2010 IP
  6. tolra

    tolra Active Member

    Messages:
    515
    Likes Received:
    36
    Best Answers:
    1
    Trophy Points:
    80
    #6
    The code depends on what you have there already, but the logic reads something like:
    
    id = extract_last_segment_of_request
    if(id is_a_number) {
      property = select_from_database(id);
      if(property not_found)
        show_404_error
      else {
        if(request_url not_equal expected_url_for_property)
          issue_301_redirect_to(expected_url_for_property)
        else
          show_property_page
      }
    }
    else
      show_403_error
    
    Code (markup):
    With the above you'd route all requests to the PHP script. You can use hashes to speed up matches for the folder structure.

    The following is an example of extracting the trailing ID from the request and keeping an array of the elements in the path. You can't just use it as it needs to be fitted with the rest of the system that you have, that needs a knowledge of the database structure and the existing PHP. It may be the database structure will need to be adjusted to make it perform correctly.

    <?php
    
    $request = explode('/', trim(preg_replace('/[\?#].*$/', '', $_SERVER['REQUEST_URI']), '/'));
    $id = array_pop($request);
    if($id === null || !preg_match('/^\d+$/', $id))
    	echo "invalid id do error condition";
    else
    	echo "valid id, thus far, id = $id";
    
    ?>
    PHP:
    Really the script developers should be building from the start to support these features as you want to minimise database queries and processing time so initial poor design will come back and bite you the more nested your property is within folders.
     
    tolra, Apr 24, 2010 IP