views:

74

answers:

3

Could anyone explain the following line please?

RewriteRule ^(.*)$ /index.php/$1 [L]

Thanks in advance.

+4  A: 

That will cause every request to be handled by index.php, which can extract the actual request from $_SERVER['REQUEST_URI']

So, a request for /foo/bar will be rewritten as /index.php/foo/bar

Paul Dixon
+6  A: 

The parts of the rewrite rule break down as follows:

  1. RewriteRule
    Indicates this line will be a rewrite rule, as opposed to a rewrite condition or one of the other rewrite engine directives

  2. ^(.*)$
    Matches all characters (.*) from the beggining ^ to the end $ of the request

  3. /index.php/$1
    The request will be re-written with the data matched by (.*) in the previous example being substituted for $1.

  4. [L]
    This tells mod_rewrite that if the pattern in step 2 matches, apply this rule as the "Last" rule, and don't apply anymore.

The mod_rewrite documentation is really comprehensive, but admittedly a lot to wade through to decode such a simple example.

The net effect is that all requests will be routed through index.php, a pattern seen in many model-view-controller implementations for PHP. index.php can examine the requested URL segments (and potentially whether the request was made via GET or POST) and use this information to dynamically invoke a certain script, without the location of that script having to match the directory structure implied by the request URI.

For example, /users/john/files/index might invoke the function index('john') in a file called user_files.php stored in a scripts directory. Without mod_rewrite, the more traditional URL would probably use an arguably less readable query string and invoke the file directly: /user_files.php?action=index&user=john.

meagar
A: 

(I'm commenting here because I don't yet have the rep's to comment the answers)

Point #2 in meagar's answer doesn't seem exactly right to me. I might be out on a limb here (I've been searching all over for help with my .htaccess rewrites...), and I'd be glad for any clarification, but this is from the Apache 2.2 documentation on RewriteRule:

What is matched?

The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string. If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.

To me that seems to say that for a URL of

http: // some.host.com/~user/folder/index.php?param=value

the part that will actually be matched is

~user/folder/index.php

So that is not matching "all characters (.*) from the beggining ^ to the end $ of the request", unless "the request" doesn't mean what I thought it does.

Thomas Nilsson
Yep, that's correct. (And maybe this should have been it's own question?)
Tim Stone
Apache defines the `%{REQUEST_URI}` variable as (using your example) `/~user/folder/index.php` (although for reasons I won't get into, the first `/` is dropped for the `RewriteRule` evaluation). So I think saying that it matches the entirety of "the request" is fair. My previous comment failed to recognize that your `REQUEST_URI` isn't in sync with what Apache defines its value as, sorry.
Tim Stone
Sorry, my mistake. I'll edit that in from the comment. I guess what I learned, and wanted to share with other newbies, was that unless you make some specific things in your RewriteCond, what actually does get to your RewriteRule is not including the domain nor any query parameters.
Thomas Nilsson