I'm trying to configure nginx so it will load PHP files without an extension, but still pass along requests for missing files to a front controller.
I started out with a mostly working config like the following that properly loads URLs like "about.php" from webroot/about.php and properly sends all requests for missing files to webroot/index.php:
server {
listen 80;
listen 443 ssl http2;
server_name *.example.com;
root /srv/example/$host;
client_max_body_size 8M;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
large_client_header_buffers 8 32k;
ssl_certificate /etc/ssl/certs/example+ca.pem;
ssl_certificate_key /etc/ssl/private/example.key;
ssl_ciphers '...';
location / {
try_files $uri
/index.php$is_args$args;
}
location /blog {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:2368;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php\b)(.*)$;
fastcgi_param SERVER_NAME $host;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_index index.php;
include fastcgi.conf;
fcgi_pass php-fpm;
}
}
I attempt to add a .php
arg to the try_files like the following so I can load URLs like /about from webroot/about.php:
location / {
try_files $uri
$uri.php
/index.php$is_args$args;
}
Now, /about.php loads as expected, but /about downloads the file. I can't figure out how to force an internal redirect while maintaining the catch-all for the front controller. I've seen several people suggest removing =404, but that's not the issue here.
error log (/about): https://pastebin.com/XbdjLri4
173.196.243.178 - - [16/May/2017:21:35:03 +0000] "GET /about HTTP/1.1" 200 6176 "-" "Wget/1.18 (linux-gnu)"
error log (/about.php): https://pastebin.com/ay32GZ0m
173.196.243.178 - - [16/May/2017:21:35:10 +0000] "GET /about.php HTTP/1.1" 200 25848 "-" "Wget/1.18 (linux-gnu)"
The issue here is that the value of request URI nginx sees here after
try_files
is stillabout
. Since there is no otherlocation
for that, it simply sends the file to browser.I think this approach would work:
Here we check separately if the requested file exists on the server. If it does not, then we rewrite the URL if it does not have the
.php
extension, and add the PHP extension to it.Then we execute the
try_files
.