使用 try_files 并在 NGINX 位置块中重写,使用默认的前端控制器文件
Using try_files and rewrite within an NGINX location block, with a default front-controller file
我正在从旧框架迁移到 php 中的新框架。旧框架每个 URL 都有一个登陆页面,例如:
test.com/page1
将被路由到 public_directory/page1.php
test.com/another_page
将被路由到 public_directory/another_page.php
等
以下块用于这些请求:
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php;
}
location @php {
rewrite ^(/[^/]+)$ .php last;
rewrite ^(/[^/]+)/(.*)$ .php?q= last;
}
新框架使用前端控制器,每个请求都需要指向public_directory/front_controller.php
。在我们迁移时,我们将删除旧的登陆文件,这是我们识别哪些页面使用新框架的方式。
我认为可行的是以下,在 @php
块之后,将默认参数添加到 front_controller.php
:
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php /front_controller.php?$arg;
}
location @php {
rewrite ^(/[^/]+)$ .php last;
rewrite ^(/[^/]+)/(.*)$ .php?q= last;
}
如果@php重写块不匹配一个文件,那么它应该默认为/front_controller.php?arg
;但是,我发现现在 @php 被忽略了,nginx
直接转到 front_controller.php。我哪里出错了,为什么 @php 重写现在被忽略了?
try_files
指令需要一个文件列表,后跟 URI/命名位置/HTTP 错误代码,如果列表中的 none 个文件存在,将使用这些文件。假设您的站点根目录是 /home/user/www
并且您的请求是 http://example.com/some/path
此配置检查是否存在以下 files/directories:
/home/user/www/some/path
文件,如果找到该文件,其内容将在响应正文中返回。
/home/user/www/some/path/
目录,如果这个目录存在,它会检查所有可能用 index
指令定义的索引文件,第一个找到的文件将被使用。如果在此目录中找不到索引文件,nginx returns 目录内容如果有 autoindex on;
或 HTTP 403 Forbidden 否则。
/home/user/www@php
文件。很明显,这个文件是找不到的。
如果 none 这些检查成功,nginx 将遵循定义为最后一个参数的 URI(或命名位置)(在本例中为 /front_controller.php?$arg
)。
你可以做的是尝试类似
location ~ ^(/[^/]+)$ {
try_files .php /front_controller.php?$arg;
}
location ~ ^(?<script>/[^/]+)/(?<param>.*)$ {
rewrite ^ $script?q=$param last;
}
但是我不明白 $arg
变量应该来自哪里。也许你的意思是 $is_args$args
?
更新
我错了,您可以使用 try_files
指令检查 php 脚本是否存在,但该脚本不会传递到您的 php 处理程序位置块。你的任务引起了我的兴趣,最后我得到了一些工作:
# backup original args
set $original_args $args;
if ($uri ~ "^(/[^/]+)(?:/(.*))?$") {
set $script .php;
set $param ;
}
if ($param) {
set $args "q=$param";
}
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php;
}
location @php {
if ( !-f $document_root$script ) {
# old landing php file is absent, restore original args and rewrite URI to /front_controller.php
set $args $original_args;
set $script /front_controller.php;
}
rewrite ^ $script last;
}
我正在从旧框架迁移到 php 中的新框架。旧框架每个 URL 都有一个登陆页面,例如:
test.com/page1
将被路由到public_directory/page1.php
test.com/another_page
将被路由到public_directory/another_page.php
等
以下块用于这些请求:
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php;
}
location @php {
rewrite ^(/[^/]+)$ .php last;
rewrite ^(/[^/]+)/(.*)$ .php?q= last;
}
新框架使用前端控制器,每个请求都需要指向public_directory/front_controller.php
。在我们迁移时,我们将删除旧的登陆文件,这是我们识别哪些页面使用新框架的方式。
我认为可行的是以下,在 @php
块之后,将默认参数添加到 front_controller.php
:
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php /front_controller.php?$arg;
}
location @php {
rewrite ^(/[^/]+)$ .php last;
rewrite ^(/[^/]+)/(.*)$ .php?q= last;
}
如果@php重写块不匹配一个文件,那么它应该默认为/front_controller.php?arg
;但是,我发现现在 @php 被忽略了,nginx
直接转到 front_controller.php。我哪里出错了,为什么 @php 重写现在被忽略了?
try_files
指令需要一个文件列表,后跟 URI/命名位置/HTTP 错误代码,如果列表中的 none 个文件存在,将使用这些文件。假设您的站点根目录是 /home/user/www
并且您的请求是 http://example.com/some/path
此配置检查是否存在以下 files/directories:
/home/user/www/some/path
文件,如果找到该文件,其内容将在响应正文中返回。/home/user/www/some/path/
目录,如果这个目录存在,它会检查所有可能用index
指令定义的索引文件,第一个找到的文件将被使用。如果在此目录中找不到索引文件,nginx returns 目录内容如果有autoindex on;
或 HTTP 403 Forbidden 否则。/home/user/www@php
文件。很明显,这个文件是找不到的。
如果 none 这些检查成功,nginx 将遵循定义为最后一个参数的 URI(或命名位置)(在本例中为 /front_controller.php?$arg
)。
你可以做的是尝试类似
location ~ ^(/[^/]+)$ {
try_files .php /front_controller.php?$arg;
}
location ~ ^(?<script>/[^/]+)/(?<param>.*)$ {
rewrite ^ $script?q=$param last;
}
但是我不明白 $arg
变量应该来自哪里。也许你的意思是 $is_args$args
?
更新
我错了,您可以使用 try_files
指令检查 php 脚本是否存在,但该脚本不会传递到您的 php 处理程序位置块。你的任务引起了我的兴趣,最后我得到了一些工作:
# backup original args
set $original_args $args;
if ($uri ~ "^(/[^/]+)(?:/(.*))?$") {
set $script .php;
set $param ;
}
if ($param) {
set $args "q=$param";
}
location / {
limit_req zone=globallimit burst=20 nodelay;
try_files $uri $uri/ @php;
}
location @php {
if ( !-f $document_root$script ) {
# old landing php file is absent, restore original args and rewrite URI to /front_controller.php
set $args $original_args;
set $script /front_controller.php;
}
rewrite ^ $script last;
}