I'm interested in switching from Apache/mod_php to Nginx for some non-CMS sites I'm running. The sites in question are either completely static HTML files or simple PHP, but the one thing they have in common is that I'm currently using Apache's mod_negotiation to serve them up without file extensions. I'm not concerned with actual content negotiation; I'm using this just so I don't have to use file extensions in my URLs.

For example, the file at /info/contact.php is accessed via a URL of just /info/contact

The actual file is a .php file in that location, but I don't use the extension in the URLs. This gives me slightly shorter, cleaner URLs and also doesn't expose what's essentially a meaningless implementation detail to the user. In Apache, all this takes is enabling mod_negotiation and adding +MultiViews to the Options for the site. In Nginx I gather I'll be rewriting somehow but being new to Nginx, I'm not exactly sure how to do it.

These sites are currently working fine proxied from Nginx to Apache, but I'd like to try running them solely with Nginx/fastcgi. They work fine this way as long as I'm using the extensions, so the fastcgi aspect is working great. My concern now is just with removing those extensions.

It's important to keep in mind that the filename is not always in the URL, in the case of subdirectories. That is,

/foo/bar should look for /foo/bar.php or /foo/bar/index.php

/foo/ should look for /foo/index.php

Is there a simple way to achieve this with Nginx or should I stick with proxying to Apache?


You don't need any tedious rewrites, try_files works perfectly for this. It's essentially only one line.

server {
    server_name foo.com;
    root /your/root/path;
    index index.php;

    location /
        try_files $uri.php $uri/ /notfound.html;

    # Your standard PHP location and everything else is still required here.
  • That almost works, but not quite. That's where I ran into a wall originally; I can get this working for URLs that contain a filename (eg, /foo going to /foo.php) but I get "No input file specified" errors for directories, such as /subdir/ or even just the root of the site - the index file is not loaded. (my try_files line is exactly as you wrote it) – Kenn Dec 11 '10 at 16:36
  • 1
    That's a completely separate issue that has to do with your fastcgi SCRIPT_FILENAME variable being wrong. You'll need to post your configuration file if you want help with that. – Martin Fjordvald Dec 11 '10 at 22:32
  • Aha! Got it. My SCRIPT_FILENAME was actually ok but I found the answer while double checking that. Adding 'fastcgi_index index.php;' fixed the problem. Thanks for your help. – Kenn Dec 12 '10 at 19:12
  • @Kenn Remember to accept the answer that resolved your problem, so that others know the question has been resolved. – Michael Hampton Dec 21 '12 at 18:47

Alternatively you can use:

try_files $uri $uri/ index.php;

without the / in front of index.php it would look for /foo/bar/index.php if it couldn't find /foo/bar/somethingelse.php. (most people have /index.php as the fall back, as that is normally what would work with wordpress and similar CMSes).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.