2

I want Nginx to load only index.php on every URL coming in

example.com/urlb?id=1

example.com/urlc?id=2

example.com/urld?id=3

my /etc/nginx/sites-available/default looks as the following -

server { listen 80; listen [::]:80; root /var/www/html; index index.php index.html index.htm; server_name html; location ~ \$ { try_files /index.php$is_args$args; include snippets/fastcgi-php.conf; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } } 

I want for all the URL above or any URL in the feature to always load index.php

2 Answers 2

2
  1. Location you used will match only the requests containing $ symbol, that's definitely not what you want.
  2. Using the try_files directive you must specify at least one file/folder to check. The easiest way to specify the file that would fail the existence check is to specify dev/null.

So your location should look like (wrong example! see the update to answer)

 location / { try_files /dev/null /index.php$is_args$args; include fastcgi.conf; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } 

or, without the try_files directive

 location / { include fastcgi.conf; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } 

Update @ 2025.01.22

It turns out that two of the three configuration variants where the try_files directive was being used, contain mistakes regarding the usage of this directive.

The variant I proposed:

try_files /dev/null /index.php$is_args$args; 

will result in an internal redirection loop. Additionally, using /dev/null as the first parameter of the try_files directive offers no performance benefit, contrary to what is suggested here.

The variant proposed by @TeroKilkanen:

try_files /index.php$is_args$args =404; 

is closer to being correct. However, the $is_args and $args nginx variables should not be used in this context because they will be treated as part of the physical filename rather than the query string. Consequently, any request with a query string will fail with this configuration.

Moreover, the snippets/fastcgi-php.conf file (a configuration snippet packaged with nginx on Debian-based Linux distributions) contains the following:

# regex to split $uri to $fastcgi_script_name and $fastcgi_path fastcgi_split_path_info ^(.+\.php)(/.+)$; # Check that the PHP script exists before passing it try_files $fastcgi_script_name =404; # Bypass the fact that try_files resets $fastcgi_path_info # see: http://trac.nginx.org/nginx/ticket/321 set $path_info $fastcgi_path_info; fastcgi_param PATH_INFO $path_info; fastcgi_index index.php; include fastcgi.conf; 

If this snippet is included in the PHP location block that already contains a try_files directive, it will cause the following error during configuration validation at nginx startup:

nginx: [emerg] "try_files" directive is duplicate in ... 

That being said, there are two correct options to achieve the behavior the OP desires:

  1. Using the try_files directive to additionally check an existence of the index.php file:
    location / { try_files /index.php =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } 
  2. Skip the existence check for better performance explicitly specifying the PHP script filename (if you are certain that the index.php file always exists):
    location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } 
    Or even explicitly specifying the full path to the index.php file (this way the root directive can be omitted al all):
    location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME /full/path/to/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } 
12
  • @MichaelHampton No, this check would fail, I already used this solution in my configurations. Found this recipe here. Commented Jun 22, 2020 at 5:17
  • this solution give an error when trying to restart my Nginx Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details. Commented Jun 22, 2020 at 5:25
  • this is the code now server { listen 80; listen [::]:80; root /var/www/html; index index.php index.html index.htm; server_name html; location / { try_files /dev/null /index.php$is_args$args; include snippets/fastcgi-php.conf; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } } Commented Jun 22, 2020 at 5:26
  • @MatCn What nginx -t says? Commented Jun 22, 2020 at 5:27
  • nginx: [emerg] "try_files" directive is duplicate in /etc/nginx/snippets/fastcgi-php.conf:5 nginx: configuration file /etc/nginx/nginx.conf test failed Commented Jun 22, 2020 at 5:28
1

Try the following location block instead:

location / { try_files /index.php$is_args$args =404; include snippets/fastcgi-php.conf; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } 

This satisfies the requirement of try_files needing at least two arguments. =404 is the fallback to return 404 Not Found response when index.php does not exist.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.