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?
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.
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.
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.