15

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]
</IfModule>

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;
                        fastcgi_pass    127.0.0.1:9000;
                }
        }
}

5 Answers 5

17

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.

2
  • Warning: This will not work on urls ending in .php , for example this will work: /doesNotExist.ph , but this will not work (will get 404 instead): /doesNotExist.php
    – hanshenrik
    Mar 29, 2020 at 10:46
  • It would be better to use try_files $uri $uri/ /index.php?$query_string; so query params would also be passed May 15, 2022 at 11:57
10

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;
    fastcgi_pass    127.0.0.1:9000;
}

Everything else remained largely the same.

2
  • 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. Aug 16, 2010 at 8:12
  • @Adam: yeah, I tried your code. I wanted everything to run through index.php. Thanks, though!
    – mattbasta
    Aug 17, 2010 at 18:34
2

To preserve GET arguments use the following:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}

$is_args becomes '?' if $args in not empty

Or even more simple:

location / {
    try_files /index.php$is_args$args;
}
1
  • Warning: This will not work on urls ending in .php , for example this will work: /doesNotExist.ph , but this will not work (will get 404 instead): /doesNotExist.php
    – hanshenrik
    Mar 29, 2020 at 10:48
1

After setting root dir add this

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

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

1
0

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .