Jump to content

Bloody mod_rewrite (removing trailing slash, forcing lowercase and more!)


Recommended Posts

Hello,

i'm just about to become bald, because mod_rewrite is making me tear my hair out. Basicly like alot of people, i like sexy urls, mostly because of SEO... and offcourse. It's sexy  :D

So what i need from my rewrite is the following:

  • It should 301 redirect all urls to http://www.domain.com, for instance: http://domain.com->http:///www.domain.com, www.domain.com->http://domain.com
  • If the url ends with a trailing slash, then it should be removed to avoid duplicate content, for instance: /controller/params/->/controller/params, /controller/->/controller
  • I would love if it could convert all url's to lowercase, but as far as i can tell you can only do that with RewriteMap, and you need access to apache conf for that, right??
  • Most important: it should convert urls like theese: controller/, controller/params/, controller/params/extraparam/ -> index.php?controller=$1, index.php?controller=$1&param=$2, inde.php?controller=$1&param=$2&extraparam=$3

So far i've got something like this:

 

RewriteEngine on

RewriteCond %{HTTP_HOST} ^domain\.com [NC]
RewriteRule ([a-z0-9/-]*) http://www.domain.com/$1 [R=301,L]

RewriteRule ([a-z0-9/-]*)/$ ${HTTP_HOST}/$1 [R=301,L]

RewriteRule ^([a-z0-9]+)/?([a-z0-9]*)/?([a-z0-9]*)$ index.php?worker=$1&param=$2&extraparam=$3 [L]

 

the last part seems to work, but if i end my url with a trailing slash like this: http://localhost/site/controller/ it redirects to http://localhost/C:/xampp/htdocs/site/${HTTP_HOST}/controller

 

i havn't tested the first part yet, but does it seem very wrong to any of you?? And how do i make my trailing slash rule work?! Is it possible for me to convert to lowercase, without messing with the httpd.conf? And do any of you have any other comments regarding the url structure or the rewrite patterns in general??

 

Thank you so much for taking your time to read through this rabble, and thank you for any help in advance :)

Here's my version.

RewriteEngine On

#1. redirect with the www subdomain
# you don't need to worry about [NC] for the hostname
RewriteCond %{HTTP_HOST} ^www\.
# don't redirect from a secure site
RewriteCond %{HTTPS} !on
RewriteRule .* http://www.%{HTTP_HOST}/$0 [L,R=301]

#2. remove trailing slashes
# only apply this to non-directories. apache can get confused otherwise
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)/$ /$1 [L,R=301]

#3. right, you can't easily do something like lowercasing with mod_rewrite
# write some php for it. tap into your mvc framework

#4.
# note the rewriteconds: the rules should only apply if the request doesn't exist
# controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)$ index.php?controller=$1 [L,QSA]
# controller/param
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/([^/]+)$ index.php?controller=$1&param=$2 [L,QSA]
# controller/param/extraparam
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# now a question: what about /controller/param/extraparam/anotherparam? with
RewriteRule ^/?([^/]+)/([^/]+)/([^/]+)$ index.php?controller=$1&param=$2&extraparam=$3 [L,QSA]
# the user will get a 404. you can discard the anotherparam and anything after with
#RewriteRule ^/?([^/]+)/([^/]+)/([^/]+)($|/) index.php?controller=$1&param=$2&extraparam=$3 [L,QSA]
# (ie, changing the last $ to a $|/)

Very nice!

 

This works very well for me, and i learned a few things too :D I had not thought about the [NC] on hostname, since it will always be lowercase heh :)

I do have a couple of questions though:

[*]Can i make the 2nd rule relative? My site is currently in http://localhost/site/, and when im doing http://localhost/site/controller/, it redirects to http://localhost/controller. I know i could just type in /site/$1, but it annoys me, that i have to do it manually like that :D

[*]How do you force the lowercase in PHP? Testing the url with preg_match, and then making a 301 redirect with header() ??

[*]Why do you split the last part up, into so many chunks?

[*]I'm not sure i understand the last part, with the $|/ instead of just $? i don't get any 404 by using site/controller/param/extra?param=1, when i'm using the one without

 

but thanks alot for your help, now i can finally move on! :)

I have forced PHP to make my url's lowercase by doing

$url = $_SERVER['REQUEST_URI'];
$pattern = '/([A-Z]+)/';

if(preg_match($pattern, $url)) {
    $new_url = strtolower($url);

    Header( 'HTTP/1.1 301 Moved Permanently' );
    Header( 'Location: ' . $new_url );
}

 

which seems to work right :) if this is a bad way to do it, please tell me so :)

 

i've also just found out what you ment by the last bit, so i don't need any explaination there either heh :D

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.