guice666 guice666 - 6 months ago 19
PHP Question

Why does `/` in Nginx try_files break `~ \.php$`

I'm trying to figure out why the prepending

is not allowing the
locations directive from picking up the script.

Below is a sample .conf I'm using for nginx. We're running API code, versioned out in path:

Our document_root is one directory below the version number;
exists within the version directory:

index index.php # <-- this is in here globally
location ~ ^/(?<version>v[\d\.]+) {
try_files $uri $version/index.php?$args;
# Why does this NOT work? The / stopping \.php$ from matching
# try_files $uri /$version/index.php?$args;

location ~ \.php$ {

fastcgi_pass php56;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;

I've tried all sorts of things, but can't seem to get this working. Once I remove the
it works as expected, but then my SCRIPT_FILENAME line changes from:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;


fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;

And this breaks direct PHP file calls -- something I don't want.


The first thing to note is that regex locations are evaluated in file order, so if /v1.1 matches the first location block, then /v1.1/index.php will also match the first location block. You seem to fix the problem in the wrong way by creating bad URIs with a missing leading /.

See this document for details.

You need to place your location ~ \.php$ block before your location ~ ^/(?<version>v[\d\.]+) block in order to allow .php files with the version prefix to be processed by the PHP block.