I am relatively new to mod_rewrite, but have a site which I would like to have "pretty urls." Similarly to SO :).

I am attempting to have things like: "http://www.whatever.com/search/test" get rewritten to "http://www.whatever.com/search.php?q=test" and have had some limited success. I believe that content negotiation is getting in my way...

For starters here's my test .htaccess file:

RewriteEngine on
RewriteBase /~user/mysite/

RewriteRule ^search$ search/ [R]
RewriteRule ^search/([^/]*)/?$ search.php?q=$1 [L]

Which unfortunately, does redirect to search.php, but does not pass my param in the q variable. However this does work:

RewriteEngine on
RewriteBase /~user/mysite/

RewriteRule ^search$ search/ [R]
RewriteRule ^search/([^/]*)/?$ s.php?q=$1 [L] # here i've renamed the search.php to s.php to dodge the content negotiation that is happening..

In fact, if I remove the rules all together, I get the same result as with the first version of the file. So my conclusion is that since apache is happily redirecting "foo" to "foo.php" even without any mod_rewrite rules, that it must be the content negotiation that is taking care of it. (This is further verified by the fact if I renamed my foo.php to foo.html, it still will find the file if i just go to "foo").

So, the question is. How do I properly use mod_rewrite with regard to content negotiation? Can I disable it for a particular file? Is there a way to ensure that my mod_rewrite rules happen before the content negotiation happens?

If it is relevant, here is the conf file for the mod_userdir part of my apache conf (this test site is in my user's homedir/public_html):

# Settings for user home directories

<IfDefine USERDIR>
<IfModule userdir_module>

# UserDir: The name of the directory that is appended onto a user's home
# directory if a ~user request is received.  Note that you must also set
# the default access control for these directories, as in the example below.
UserDir public_html

# Control access to UserDir directories.  The following is an example
# for a site where these directories are restricted to read-only.
<Directory /home/*/public_html>
    AllowOverride FileInfo AuthConfig Limit Indexes
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    	Order allow,deny
    	Allow from all
    <LimitExcept GET POST OPTIONS>
    	Order deny,allow
    	Deny from all

# Suexec isn't really required to run cgi-scripts, but it's a really good
# idea if you have multiple users serving websites...
<IfDefine SUEXEC>
<IfModule suexec_module>
<Directory /home/*/public_html/cgi-bin>
    Options ExecCGI
    SetHandler cgi-script


Accepted Answer

Look for this option in your configuration.

Options +Multiviews

It will look for


and redirect them to

/foo.[any file]

based upon if it exists and if it fits the content-type requested.

Change the option to this to disable this.

Options -Multiviews
Written by Roy Rico
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki