views:

595

answers:

3

Can anyone explain what this mod_rewrite rule is doing?

I'm trying to comment the file, but the code seems to state the opposite of what I think it's doing

# Enable rewriting of URLs
RewriteEngine on


# Allow specified file types to be accessed
# Thing to test = URL
# Condition = not starting with  
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt)


# RewriteRule will only be performed if the preceeding RewriteCond is fulfilled
# Remove index.php from all URLs     
# Pattern = anything (0 or more of any character)
# Substitution = index.php + the rest of the URL    
RewriteRule ^(.*)$ /index.php/$1 [L]
+2  A: 

If the URL does not start with index.php or images or css or js or robots.txt, the string "/index.php/" is prefixed.

As index.php is probably an executable php app, the index.php then can read the rest of the URL from its cgi environment. (it is stored in ${PATH_INFO})

Sec
+3  A: 
^ = begin of line
( = begin group
.* = any character, any number of times
) = end group

The $1 in the second part is replaced by the group in the first part.

Is this a Symfony rule? The idea is to pass the whole query string to the index.php (the front controller) as a parameter, so that the front controller can parse and route it.

Roel
Actually it's from CodeIgniter. So is the front controller doing the rewriting?
meleyal
There is no front controller however there is a default_controller. See the CI documentation. http://codeigniter.com/user_guide/general/routing.html
gradbot
No, mod_rewrite does the rewriting. I'll post a new answer to explain more, I can't fit it in these 300 characters.
Roel
+5  A: 

The browser sends a request to the server (Apache, since you're using mod_rewrite):

GET profile/edit

Apache accepts this request and sees in its configuration files that you've configured it to pass all requests through mod_rewrite. So, it sends the string 'profile/edit' to mod_rewrite. Mod_rewrite then applies the rules you specified to it, which then transforms the request (in the way I explained in my previous post) to 'index.php/profile/edit'. After mod_rewrite is done, Apache continues processing the request, and sees 'oh, this guy is requesting the file index.php'. So it calls the php interpreter which then parses and executes index.php - and gets '/profile/edit' as arguments. The php code (CI in your case) parses these arguments and knows how to call the right module in your application.

So basically, it's a way to always call index.php, even when the url doesn't specify index.php. In that way, index.php works as the front controller: it routes all requests to the right location in your application.

Roel
Great explanation, thank you. But then how is 'index.php' getting removed from my URLs?My URLs look like domain.com/profile/edit
meleyal
What do you mean 'removed'? CI presumably has a way to specify whether or not you want to include 'index.php' in the urls you emit (I assume that in CI you need to use function calls to output url's, that's how it works in Symfony - I only have experience with that).
Roel
So, that function can determine if the setting to include index.php in your urls is on or off. The clients (browsers) only ever see the url without the index.php. On an incoming request, mod_rewrite rewrites adds the index.php, and the php code doesn't emit urls with index.php.
Roel
There's a config setting 'index_page', the comments say... "If you are using mod_rewrite to remove the page set this variable so that it is blank." I am using mod_rewrite, but as stated the rules there are *adding* index.php. So I'm still unsure who/what/how is removing index.php from the URLs? :/
meleyal
I still don't understand what your problem is. How do you mean 'removing index.php from the URLs'? At what point is it generated, i.e. where do you put in a version *with* index.php and where does it come out *without* it?
Roel
I thought if everything goes through index.php (front controller), then it would always show in the URL (index.php/profile/edit)
meleyal
No, the whole point of using mod_rewrite is that you can show url's that don't have index.php in them, but make apache+php work as if it *is* there. For every incoming request, 'index.php' is 'inserted' into the query string.
Roel
OK, that makes sense ( finally ;). Thanks for your patience Roel
meleyal