I have a PHP script that handles script routing and does all sorts of fancy things. It was originally designed for Apache, but I'm trying to migrate it to nginx for a few of my boxes. Right now, I'm trying to smooth things out on a test server.

So the way the script works is that it intercepts all HTTP traffic for the directory (in Apache) using a .htaccess file. Here's what that looks like:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.+$ index.php [L]

Pretty straightforward. All requests are run through index.php, plain and simple.

I'm looking to mimic that behavior on nginx, but I haven't yet found a way. Anybody have any suggestions?

Here's a copy of my nginx.conf file at the moment. Note that it was designed for me to just try to get it working; mostly a copy/paste job.

user www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    # multi_accept on;

http {
        include         /etc/nginx/mime.types;
        default_type    text/plain;
        include         /etc/nginx/conf.d/*.conf;
        server {
                listen          80;
                server_name     swingset.serverboy.net;

                access_log      /var/log/nginx/net.serverboy.swingset.access_log;
                error_log       /var/log/nginx/net.serverboy.swingset.error_log warn;

                root            /var/www/swingset;

                index           index.php index.html;
                fastcgi_index   index.php;

                location ~ \.php {
                        include /etc/nginx/fastcgi_params;
                        keepalive_timeout 0;
                        fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;

Add this,

 location / {
                    try_files $uri $uri/ /index.php;

What it does is it first check the existence of $uri and $uri/ as real files/folders and if they don't exist will just go through /index.php (that is my setup for Zend framework where routing is done through index.php) - of course if you need to pass some parameters, just append to the /index.php a ?q= at the end and it will pass the parameters.

Make sure that the try_file directive is available from version 0.7.27 and onward.


I figured it out on my own! Yeah!

All I needed for the location block was:

location /  {
    include /etc/nginx/fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME  $document_root/index.php;

Everything else remained largely the same.

  • Did you try what I wrote below? Also it does mean that all of your static files will go through index.php - not sure you want that. – Adam Benayoun Aug 16 '10 at 8:12
  • @Adam: yeah, I tried your code. I wanted everything to run through index.php. Thanks, though! – mattbasta Aug 17 '10 at 18:34

After setting root dir add this

if (!-e $request_filename)
    rewrite ^/(.*)$ /index.php?/$1 last;

According to your need you may change regex as you need ruling query_string to index.php


One very important pitfall to be careful of when your target is a PHP file is to make sure whatever return / rewrite rule you use does not supercede the location ~ \.php directive. If this happens, nginx will serve your PHP file without rendering it, revealing the PHP source code. This can be catastrophic.

The safest way is already provided, location / { try_files $uri $uri/ /index.php; }

Make sure you also set index index.php in your location / block and uncomment the location ~ \.php block included in the default config file.

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.