为什么 try_files 中的 `/` 会中断 `~ \.php$`
Why does `/` in try_files break `~ \.php$`
我想弄清楚为什么前置 /
不允许 \.php$
locations 指令获取脚本。
下面是我用于 nginx 的示例 .conf。我们是 运行 API 代码,在路径中版本化://domian.com/v#.#/endpoint/uri
我们的document_root是版本号下一级目录; index.php
存在于版本目录中:path/to/sites/public/v1.0/index.php
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;
[...]
}
我已经尝试了各种方法,但似乎无法正常工作。一旦我删除 /
它按预期工作,但随后我的 SCRIPT_FILENAME 行从:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
收件人:
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
这会中断直接 PHP 文件调用——这是我不想要的。
编辑:解决方案:回答如下:问题与匹配顺序有关。模式匹配是最先发现的,而不是最后发现的。
调换顺序成功了。它在第一个 try_files
中失败,因为该模式明确地寻找以 /
.
开头的模式
我正在阅读:http://nginx.org/en/docs/http/request_processing.html
A request “/index.php” is also matched by the prefix location “/”
first and then by the regular expression “.(php)$”. Therefore, it is handled by the latter location and the request is passed to a FastCGI server listening on localhost:9000.
首先要注意的是,正则表达式位置是按文件顺序计算的,因此如果 /v1.1
匹配第一个位置块,那么 /v1.1/index.php
也将匹配第一个位置块。您似乎通过创建缺少前导 /
.
的错误 URI 来以错误的方式解决问题
详情见this document。
您需要将 location ~ \.php$
块放在 之前 您的 location ~ ^/(?<version>v[\d\.]+)
块以允许 .php
具有版本前缀的文件由 PHP 块处理。
我想弄清楚为什么前置 /
不允许 \.php$
locations 指令获取脚本。
下面是我用于 nginx 的示例 .conf。我们是 运行 API 代码,在路径中版本化://domian.com/v#.#/endpoint/uri
我们的document_root是版本号下一级目录; index.php
存在于版本目录中:path/to/sites/public/v1.0/index.php
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;
[...]
}
我已经尝试了各种方法,但似乎无法正常工作。一旦我删除 /
它按预期工作,但随后我的 SCRIPT_FILENAME 行从:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
收件人:
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
这会中断直接 PHP 文件调用——这是我不想要的。
编辑:解决方案:回答如下:问题与匹配顺序有关。模式匹配是最先发现的,而不是最后发现的。
调换顺序成功了。它在第一个 try_files
中失败,因为该模式明确地寻找以 /
.
我正在阅读:http://nginx.org/en/docs/http/request_processing.html
A request “/index.php” is also matched by the prefix location “/” first and then by the regular expression “.(php)$”. Therefore, it is handled by the latter location and the request is passed to a FastCGI server listening on localhost:9000.
首先要注意的是,正则表达式位置是按文件顺序计算的,因此如果 /v1.1
匹配第一个位置块,那么 /v1.1/index.php
也将匹配第一个位置块。您似乎通过创建缺少前导 /
.
详情见this document。
您需要将 location ~ \.php$
块放在 之前 您的 location ~ ^/(?<version>v[\d\.]+)
块以允许 .php
具有版本前缀的文件由 PHP 块处理。