Nginx Rewriting : PHP file inside of Location directive not served
I am trying to redirect a subdirectory to a php file. Instead of serving the file, it downloads it, meaning that it does not read it as a php file.
More exactly it does not enter the fastcgi location ~ \.php$
directive.
Some interesting facts :
- Everything works perfectly well for the
admin
bloc but not for thelogin
block. - When I move the
location ~ \.php$
directive above thelogin
one and that I change^~ /login
into~ /login
, it works exept for the rewrite rulerewrite ^/login/(.+\.php)$ /$1 last;
.
I did read the Wiki Nginx documentation on the topic so I am aware of the priorities in which nginx read the location directives but that does not tell me how to deal with this case! I also read
- the similar question https://stackoverflow.com/questions/10126117/need-help-understanding-configuring-an-nginx-location-directive (unanswered)
- https://stackoverflow.com/questions/11961323/howto-setup-window-nginx-virtual-directory-with-php-support that I tried to implement with no success
- https://stackoverflow.com/questions/1011101/nginx-location-directive-doesnt-seem-to-be-working-am-i-missing-something that cover the case of a real (not virtual) subfolder.
Here is the config:
server {
listen 80;
server_name tyba-one.com *.tyba-one.com;
root /var/www/tyba/public_html;
rewrite_log on;
error_page 404 /404.php;
client_max_body_size 4M;
if ($host ~* ^www\.(.*)){
set $host_without_www $1;
rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
}
location = / {
rewrite ^/$ /index.php last;
}
location ^~ /login {
rewrite ^(/login)$ $1/ permanent;
rewrite ^/login/$ /login.php last;
rewrite ^/login/(.+\.php)$ /$1 last;
}
location ^~ /admin {
rewrite ^(/admin)$ $1/ permanent;
rewrite ^/admin/$ /page_builder.php last;
rewrite ^/admin/(.+\.php)$ /$1 last;
}
location ~ \.php$ {
try_files $uri =404;
include /opt/nginx/conf/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/tyba/public_html$fastcgi_script_name;
}
}
I would like to understand what's going on and how to deal with such situations.
Solution 1:
nginx only processes one location block at each nesting level, and so /login.php
is handled by the ^~ /login
block and not the ~ \.php$
block. Since you only have rewrite statements in your location blocks, you actually don't need the location blocks at all (as long as the rewrite matches are specific enough, which yours are). Just move your rewrite statements into the root of the server
block so that requests for /login
and /admin
still use the \.php$
location block:
rewrite ^/$ /index.php last;
rewrite ^(/login)$ $1/ permanent;
rewrite ^/login/$ /login.php last;
rewrite ^/login/(.+\.php)$ /$1 last;
rewrite ^(/admin)$ $1/ permanent;
rewrite ^/admin/$ /page_builder.php last;
rewrite ^/admin/(.+\.php)$ /$1 last;
location ~ \.php$ {
...
}