I've been having trouble getting Nginx rewrites to work.

On Apache I had the following rewrite, which directed all requests that did not request a PHP file to index.php:

Options +FollowSymLinks 
RewriteEngine on
RewriteRule !^(.*)\.php$ ./index.php [QSA,L]

The same should work on Nginx, but it does not. This rewrite does nothing (it throws 404 pages for every request):

rewrite !^(.*)\.php$ ./index.php last;

But if I remove the exclamation mark, then the rewrite does work, doing the exact opposite (it redirects all *.php file requests to index.php file):

rewrite ^(.*)\.php$ ./index.php last;

Why doesn't the reverse work in Nginx like the way it does with Apache? What should I change? The one with exclamation mark throws either 404 errors or 'No input file specified.' errors.


Use a couple of Location blocks. Something like:

location ~ *.php$ { }

location / {
  rewrite ^(.*)$ ./index.php last;

The first one should catch all the files ending in .php and just access them. The second one will catch everything else and rewrite to ./index.php.


This was the correct solution:

# Make sure to set this as your actual server WWW root
root html;

# Index file
index index.php;

# Rewrite that directs everything, except PHP to index file
# Make sure you place this before your "location ~ \.php$ {" for the server configuration.
location / {
    rewrite ^ ./index.php last;

location ~ \.php$ {
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;

Basically the first one says that everything should be directed to PHP and the second location block is your typical PHP directive. So once the first rewrite happens, it will trigger the second (thus PHP).

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.