views:

240

answers:

7

Hi, I'm having a hard time with .htacces. I want to create friendly URLs for a site I'm working on...

Basically I want to convert this:

http://website.com/index.php?ctrl=pelicula&id=0221889
http://website.com/index.php?ctrl=pelicula&id=0160399&tab=posters

Into this:

http://website.com/pelicula/0221889/
http://website.com/pelicula/0221889/posters/

In case I need it later I would also want to know how to add the article title to the end of the URL like this (I'm using PHP):

http://website.com/pelicula/0221889/the-article-name/
http://website.com/pelicula/0221889/the-article-name/posters/

Note: Stackoverflow method is also good for me, for example the url of this question is:

http://stackoverflow.com/questions/3033407/htacces-to-create-friendly-urls-help-needed

But you can put anything after the id and it will also work. like this:

http://stackoverflow.com/questions/3033407/just-anything-i-want

I have used some automatic web tools for creating the .htacces file, but its not working correctly. So I ask for your help.

I will also be glad if you can recommend .htacces best practices and recommendations..

EDIT: based on some answers I get here I put this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
</IfModule>

But I get the default host 'page not found' error.

I also tried:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^/]+)/(\d+)/([^/]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
    RewriteRule ^([^/]+)/(\d+)/?$         index.php?ctrl=$1&id=$2 [QSA,L]
    RewriteRule ^([^/]+)/?$               index.php?ctrl=$1 [QSA,L]
</IfModule>

This also does not work. It takes me to my default 404.php page.

mod_rewrite is enabled and working.

Help!

A: 

The first one assuming your .htaccess file is in the root:

RewriteRule ^([a-zA-Z]+)/([0-9]+)(/)?$ index.php?ctrl=$1&id=$2

The second:

RewriteRule ^([a-zA-Z]+)/([0-9]+)/([a-zA-Z]+)(/)?$ index.php?ctrl=$1&id=$2&tab=$3

or if it's always posters rather than different tabs:

RewriteRule ^([a-zA-Z]+)/([0-9]+)/posters(/)?$ index.php?ctrl=$1&id=$2&tab=posters

I added the (/)? which should mean the URI will work with or without trailing slash.

As for the other I'd probably always keep the article at the end so the rewrite or add another /value so the rewrite knows the difference between the tab and article or exclude dashes from the regex.

great, this is the only line I need to put inside the htacces file?
Jonathan
+2  A: 

In the document root for http://website.com/ I'd put an htaccess file like this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

Then in your PHP script you can manipulate the $_GET['url'] variable as you please:

$path_components = explode('/', $_GET['url']);
$ctrl=$path_components[0];
$id=$path_components[1];
$tab=$path_components[2];
LeguRi
I need to change all the web application to use this? I mean, I need to change all the $_GET in every single page?
Jonathan
@Jonathan: No, that's the whole point of it! You'll only have that code in the index.php page. Then index.php can decide what to do and `include` the needed page(s) depending on the $_GET variables
nico
A: 

To have this url :

http://website.com/pelicula/0221889/posters

rewritten to this:

http://website.com/index.php?ctrl=pelicula&amp;id=0221889&amp;tab=posters

I would do this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
</IfModule>

You have to choose if you want to put the title after the id and do it all the time, because of the tab variable being in last position: you have to know if it's going to be number 3 or number 4. If you do this:

RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?([^/]*)$ index.php?ctrl=$1&id=$2&tab=$4 [QSA,L]

the third parenthesis is not captured, and can therefore contain anything.

Hope that helps

jfoucher
I put this in the .htacces file but its not working, any idea why?
Jonathan
Well, what king of eeor do you get ?Do you have mod_rewrite enabled?
jfoucher
yes, everything is enabled. It just does't find the page..
Jonathan
+3  A: 

Just tested this locally and it seems to do what you need:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^/.]+)(?:/)?$ /index.php?ctrl=$1 [L]
    RewriteRule ^([^/.]+)/([^/.]+)(?:/)?$ /index.php?ctrl=$1&id=$2 [L]
    RewriteRule ^([^/.]+)/([^/.]+)/([^/.]+)(?:/.*)?$ /index.php?ctrl=$1&id=$2&tab=$3 [L]
</IfModule>

This is what it does:

These rewrites will work with or without a trailing slash - if you want them to work only without the slash, remove the (?:/)? from the end of the first two rewrites. You can also use mod_rewrite to add or remove a trailing slash as required.

cam8001
Its not working on my web host. I get this error: Internal Server Error. The server encountered an internal error or misconfiguration and was unable to complete your request.Any idea?
Jonathan
Try removing the slash from in front of index.php on all of the rewrite rules.
cam8001
I removed the slashes, same error. I think it might be a syntax error because when I tried the code provided by 'jfoucher' I don't get this problem...
Jonathan
Do you have access to the server logs? Can you see what is happening in the rewrite log?
cam8001
I have no access to serlver logs, please read my other question http://stackoverflow.com/questions/3076122/php-routing-for-friendly-urls-help
Jonathan
A: 

Make sure you don't have any other .htaccess file higher up on the directory tree that's conflicting with your site's .htaccess.

A: 

I use this in my .htaccess file

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* rewrite.php [L]

Basically if it doesn't exist as a file or a directory, use rewrite.php and let that take care of URL parsing etc. That is I believe the most basic way you can rewrite.

Also, check out the results of var_dump($_SERVER) (somewhere you know works) to see if what you think is the topmost directory really IS the topmost directory, eg: you may be writiting to /var/www/domain/www/index.php instead of /var/www/domain/index.php

Kristoffer S Hansen
A: 

Based on experience, I would recommend adjusting your URI scheme to make it easier to only apply the rule to URIs that you KNOW are re-written. For example

Convert this:

http://website.com/index.php?ctrl=pelicula&amp;id=0221889
http://website.com/index.php?ctrl=pelicula&amp;id=0160399&amp;tab=posters

Into this (I have put the word "stuff", but this really ought to be something that describes what you are likely to find, i.e. "shop" or "library" or whatever this content is):

http://website.com/stuff/pelicula/0221889/
http://website.com/stuff/pelicula/0221889/posters/

To achieve this, you would put a .htaccess file in the top-level folder of your website that contains the following rules:

RewriteEngine on
RewriteRule ^stuff/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [L,NC,QSA]
RewriteRule ^stuff/([^/\.]+)/([^/\.]+)/?$ index.php?ctrl=$1&id=$2 [L,NC,QSA]

By having the "stuff" part of the address (renamed to something appropriate), you won't accidentally rewrite other assets such as images, CSS includes and JavaScript includes.

As a side note, you've mentioned:

This also does not work. It takes me to my default 404.php page.

Where is your 404 error redirection declared?

Sohnee