Avoid Common Nginx+PHP Pitfalls with a Clean Configuration
Copy‑pasting outdated Nginx‑PHP tutorials often introduces hidden bugs, so this article explains typical configuration mistakes, the inheritance model, misuse of directives like index, if, and fastcgi_params, and provides a streamlined, secure configuration example.
Why simple copy‑paste can be risky
Many developers configure Nginx + PHP by copying a tutorial without fully understanding it, which can lead to subtle bugs because many online resources are outdated or contain errors.
Typical (problematic) configuration
server {
listen 80;
server_name foo.com;
root /path;
location / {
index index.html index.htm index.php;
if (!-e $request_filename) {
rewrite . /index.php last;
}
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /path$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}This configuration contains several bad practices, such as defining index inside a location block, using if for request routing, and hard‑coding the script filename.
Understanding Nginx inheritance
Nginx configuration is hierarchical: http → server → location. Inner blocks inherit values from outer blocks unless overridden. Therefore, directives like index should be placed in the server block to apply to all locations.
Problems with the if directive
The if directive is often misused; its proper role is limited to the rewrite module. For file existence checks, try_files is the appropriate directive.
try_files $uri $uri/ /index.php;Using if together with non‑rewrite directives can produce unexpected results.
FastCGI parameter files
Nginx provides two FastCGI parameter files: fastcgi_params and fastcgi.conf. The latter adds a SCRIPT_FILENAME definition:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;Because fastcgi_param is an array‑type directive, defining SCRIPT_FILENAME multiple times in the same level appends values, which can cause conflicts. Hence a separate fastcgi.conf file was introduced.
Security consideration
If PHP’s cgi.fix_pathinfo is enabled, malformed URLs may be treated as PHP scripts. A simple safeguard is to filter requests with try_files:
try_files $uri =404;Improved configuration
server {
listen 80;
server_name foo.com;
root /path;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
}
}This version removes duplicate index definitions, replaces the unsafe if with try_files, uses fastcgi.conf for a correct script filename, and adds a 404 fallback for non‑existent PHP files. Note that fastcgi_index is unnecessary when the location is already limited.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
