Answer a question

I've looks up and down and, while this has been answered dozens of times, I can't get it to work. I'm trying to get apache style multiviews on my PHP site running under nginx. In this case I don't care about all file extensions, just php. So i have my try_files directive:

try_files $uri $uri.php $uri/ $1?$args $1.php?$args

which is all good and dandy, except that when I visit a PHP page without the PHP file extension, the PHP doesn't get rendered and just gets dumped straight to the browser. I see why (PHP is only being used when the location ends in .php, but I've got no idea how to fix it. Here's my config:

server {
    listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80 default ipv6only=on; ## listen for ipv6

    root /usr/share/nginx/www;
    index index.php index.html index.htm;

    server_name inara.thefinn93.com;

    location /  {
            root /usr/share/nginx/www;
            try_files $uri $uri.php $uri/ $1?$args $1.php?$args;
    }

    location ~ ^(.+\.php)$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_index index.php;
            include fastcgi_params;
    }

    location ~ /\.ht {
            deny all;
    }
}

Answers

In your scenario, the location / is the last processed location setting. Having a try_files on it won't make it past the location ~ ^(.+\.php)$ setting (unless it ends with ".php"), therefore not being forwarded to the fastcgi upstream. You might use a named location for that purpose (locations starting with "@").

Here's an example based on your configuration:

    # real .php files only 
    location ~ ^(.+\.php)$ {
        # try_files is not needed here. The files will be checked at "location /"
        # try_files $uri =404;

        # do not split here -- multiviews will be handled by "location @php"
        # fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;

        fastcgi_pass unix:/var/run/php5-fpm.sock;

        # also not needed here/with try_files
        # fastcgi_index index.php;

        include fastcgi_params;
    }

    # pseudo-multiviews
    location @php {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;

        fastcgi_index index.php;
        fastcgi_pass unix:/var/run/php5-fpm.sock;

        # search for the split path first
        # "$uri/" is not needed since you used the index
        try_files $fastcgi_script_name $uri.php =404;
    }

    # this should also be before "location /"
    location ~ /\.ht {
        deny all;
    }

    location /  {
        root /usr/share/nginx/www;
        # if file does not exist, see if the pseudo-multiviews work
        try_files $uri @php;
    }
Logo

开发云社区提供前沿行业资讯和优质的学习知识,同时提供优质稳定、价格优惠的云主机、数据库、网络、云储存等云服务产品

更多推荐