2

I want Nginx to serve any requests for static files on its own, but if the file doesn't exist, then serve index.php which will handle it all

Currently my configuration looks like this,

server {
listen 80;
listen [::]:80;

root /home/www/example.com/htdocs;

index index.php;

server_name www.example.com;


location ~* ^[^\?\&]+\.(html|jpg|jpeg|json|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|svg|woff|ttf)$ {
    # First attempt to serve request as file, then
    # as directory, then fall back to index.php
    try_files $uri $uri/ /index.php;
    #try_files /favicon.ico =404;
}


location / {
    add_header X-Is-PHP true;
            try_files /index.php =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            # With php5-fpm:
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            include fastcgi.conf;
    }


}

This is as close as I can get, it serves any request for static files, and if it doesn't exist, serves index.php as a plaintext file. How can I get index.php passed on to the PHP interpreter?

5
  • 1
    Use the sample configuration that came with nginx. Jan 24, 2016 at 4:08
  • I only want plain files to be served by nginx, I don't want any other php files to be served on their own. I want www.example.com/index.php to be served no matter what url is requested, except only if and only if there's a static file that matches the url.
    – John Cave
    Jan 24, 2016 at 4:14
  • What are "plain files"?
    – gxx
    Jan 24, 2016 at 10:52
  • And what do you want to happen when some other PHP file is encountered? Jan 24, 2016 at 12:21
  • By "plain" files I mean static files like jpg and css. That was poor word choice on my part. @MichaelHampton I don't really mind what happens when other php files are called anymore, whether they 404 or redirect to /index.php, I just want index.php to be executed when called so I can continue developing the site.
    – John Cave
    Jan 25, 2016 at 5:14

3 Answers 3

5

try this

server {
listen 80;
listen [::]:80;

root /home/www/example.com/htdocs;

index index.php;

server_name www.example.com;


location ~* ^[^\?\&]+\.(html|jpg|jpeg|json|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|svg|woff|ttf)$ {
    # First attempt to serve request as file, then
    # as directory, then fall back to index.php
    try_files $uri $uri/ /index.php;
    #try_files /favicon.ico =404;
}

error_page 404 /index.php;

location ~ \.php$ {
            add_header X-Is-PHP true;
            #try_files $uri =404;
            try_files /index.php =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            # With php5-fpm:
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            include fastcgi.conf;
    }


}

changes

1) Added error_page 404 /index.php; so that all the requests not found on the server are redirected to index.php

2) Added "~ .php$" to location attribute.

3)If u want other PHP files to be interpreted as well, uncomment the line "#try_files $uri =404;" and comment the line "try_files /index.php =404;"

3
  • This got me slightly closer to what I want, now when I call another php file, it sends me back the source of /index.php. However, it still doesn't execute /index.php at all.
    – John Cave
    Jan 25, 2016 at 5:21
  • Oh I feel like such an idiot. It's been working this whole time but I'd been caught out by one shorttag in the /index.php file :/. I only noticed when I opened it up and realised the first php block wasn't in the source I'd been getting in the browser.
    – John Cave
    Jan 25, 2016 at 5:34
  • my index file is not in root folder, it is located on modules/home/index.php. i try much settings but not work at all, i set it as 'index /modules/home/index.php;' but work
    – Rohit
    Mar 16, 2017 at 7:23
1

location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php; } }

2
  • I tried adding this before, after and in the middle of my current location {} blocks but it had no effect. I tried using it instead of my first location block, but it was still exactly the same as before. I still get the source of /index.php sent to my browser unless there's a static file at the requested url.
    – John Cave
    Jan 25, 2016 at 5:12
  • Because you need to remove all the content from your file regexp-location (the long one), and leave only break; inside it. Avoid using try_files, it's largely misunderstood.
    – drookie
    Jan 25, 2016 at 6:09
0

To be honest you should NOT be using If. This is even mentioned in the NGINX manual on their website. A great way to achieve serving a file if it exists is to use try_files properly. Here is in the example I have provided below.

set $base_root /webhosts/website.com/webroot;
root $base_root;

#if file exists then serve it. Else Fallback to @php location directive
location / {
    try_files $uri $uri/ @php;
}

location @php { 
    rewrite ^/(.+)$ /index.php?/$1 last;
}

The example above is just using a re-write rule that I need. You should use try_files and let the 3rd argument (Fallback directive) determine what happens next.

Also make sure you set the root. If you set root to / then this is very dangerous because you open up the systems root to files you should not.

You must log in to answer this question.

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