webdevops nginx-从网址中删除.php要求 [英] webdevops nginx - remove .php requirement from url
问题描述
我有一个基于 webdevops/php-nginx:7.2
的docker,我正在尝试配置nginx以将带有或不带.php扩展名的请求路由到适当的文件./p>
如果存在 abc.php
,我需要/abc
和/abc.php
路由到 abc.php 代码>.其他所有内容都将转到
index.php
当前设置如下:
Dockerfile
包含
WEB_DOCUMENT_ROOT =/app/public复制docker/opt/docker/etc/opt/docker/etc/
opt/docker/etc/nginx/conf.d/10-location-root.conf
服务器{index index.html index.php;地点/{try_files $ uri $ uri//index.php?_url=$uri&$args;}}
/app/public
包含
index.phpabc.php
当前,此配置将除/abc.php
之外的所有内容路由到 index.php
.尝试打/abc
路由到 index.php
.
谢谢:)
编辑:使用Ivan的答案,码头工人记录了垃圾邮件:
app_1 |->执行/opt/docker/bin/service.d/nginx.d//10-init.shapp_1 |2020-10-20 10:31:59,273信息成功:nginxd进入了RUNNING状态,进程已暂停了>大于0秒(startsecs)app_1 |nginx:[emerg]未知的"_uri"多变的app_1 |2020-10-20 10:31:59,287信息退出:nginxd(退出状态1;预计不到)
如果我正确理解该系统的工作原理,请尝试以下两个文件作为开头:
-
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
位置/{try_files $ uri $ uri/@ extensionless-php;}位置@ extensionless-php {最后重写^ $ uri.php;}
-
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
位置〜\ .php $ {try_files $ uri/< DOCUMENT_INDEX>?_ url = $ uri& $ args;fastcgi_pass php;包括fastcgi_params;fastcgi_param SCRIPT_FILENAME $ request_filename;fastcgi_read_timeout< PHP_TIMEOUT> ;;}
以上配置有一个严重缺陷.如果请求的URI不是现有PHP文件的名称(带有或不带有 .php
扩展名),则 $ uri
内部nginx变量值将始终以 .php
,这是由于 @ extensionless-php
命名位置中的 rewrite
规则所致.这将导致以下情况(假设文件/app/public/some/path.php
不存在):
/some/path
=>/index.php?_url=/some/path.php
/some/path.php
=>/index.php?_url=/some/path.php
要解决此问题,我们可以将原始的 $ uri
变量值保存在名为 extensionless-php
的位置:
-
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
位置/{try_files $ uri $ uri/@ extensionless-php;}位置@ extensionless-php {设置$ original_uri $ uri;最后重写^ $ uri.php;}
-
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
位置〜\ .php $ {try_files $ uri/< DOCUMENT_INDEX>?_ url = $ original_uri& $ args;fastcgi_pass php;包括fastcgi_params;fastcgi_param SCRIPT_FILENAME $ request_filename;fastcgi_read_timeout< PHP_TIMEOUT> ;;}
此配置更好,但仍然存在缺陷.如果请求的URI以 .php
结尾,并且/app/public
目录中没有相应的PHP文件,则 $ original_uri
变量将不会将被初始化,并且 _url
查询参数将作为一个空字符串传递给后端:
/some/path
=>/index.php?_url=/some/path
/some/path.php
=>/index.php?_url =
这对于某些Web应用程序可能是可以的(空的 _url
查询参数始终表示无效的路由),但是如果我们想获取原始的URI,无论怎么做,该怎么办?我们可以借助 map
的帮助来实现>指令(极其强大的nginx功能).但是,所有 map
块都应在 server
块之外声明,因此我们需要一个附加文件:
-
/opt/docker/etc/nginx/conf.d/10-map.conf
map $ _uri $ original_uri {"$ uri;默认$ _uri;}
-
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
位置/{try_files $ uri $ uri/@ extensionless-php;}位置@ extensionless-php {设置$ _uri $ uri;最后重写^ $ uri.php;}
-
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
位置〜\ .php $ {try_files $ uri/< DOCUMENT_INDEX>?_ url = $ original_uri& $ args;fastcgi_pass php;包括fastcgi_params;fastcgi_param SCRIPT_FILENAME $ request_filename;fastcgi_read_timeout< PHP_TIMEOUT> ;;}
此 map
块意味着 $ original_uri
变量如果未修改,将等于 $ uri
一个($ _uri
变量未初始化且为空).如果 $ _ uri
变量不为空,则意味着原始的 $ uri
已被修改,并且 $ _ uri
变量现在保持其原始值,因此 $ original_uri
变量的值将设置为 $ _ uri
.此配置应与任何将原始URI保留为 _url
查询参数的请求一起使用.
I have a docker that is based off of webdevops/php-nginx:7.2
and I am trying to configure the nginx to route requests with or without the .php extension to the appropriate file.
If abc.php
exists, I need /abc
and /abc.php
to route to abc.php
. Everything else would go to index.php
Current setup looks like:
Dockerfile
contains
WEB_DOCUMENT_ROOT=/app/public
COPY docker/opt/docker/etc /opt/docker/etc/
opt/docker/etc/nginx/conf.d/10-location-root.conf
server {
index index.html index.php;
location / {
try_files $uri $uri/ /index.php?_url=$uri&$args;
}
}
/app/public
contains
index.php
abc.php
Currently this configuration routes everything to index.php
except for /abc.php
. Trying to hit /abc
routes to index.php
.
Thanks :)
Edit: Using Ivan's answer the docker logs spam:
app_1 | -> Executing /opt/docker/bin/service.d/nginx.d//10-init.sh
app_1 | 2020-10-20 10:31:59,273 INFO success: nginxd entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
app_1 | nginx: [emerg] unknown "_uri" variable
app_1 | 2020-10-20 10:31:59,287 INFO exited: nginxd (exit status 1; not expected)
If I correctly understand how this system works, lets try the two following files for the beginning:
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
location / {
try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
rewrite ^ $uri.php last;
}
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
location ~ \.php$ {
try_files $uri /<DOCUMENT_INDEX>?_url=$uri&$args;
fastcgi_pass php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout <PHP_TIMEOUT>;
}
The above configuration has one serious flaw. If the requested URI isn't the name of an existing PHP file (with or without the .php
extension), a $uri
internal nginx variable value will always end with .php
due to the rewrite
rule inside of the @extensionless-php
named location. This would lead to the following (assuming file /app/public/some/path.php
doesn't exist):
/some/path
=> /index.php?_url=/some/path.php
/some/path.php
=> /index.php?_url=/some/path.php
To fix this issue we can save the original $uri
variable value inside the extensionless-php
named location:
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
location / {
try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
set $original_uri $uri;
rewrite ^ $uri.php last;
}
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
location ~ \.php$ {
try_files $uri /<DOCUMENT_INDEX>?_url=$original_uri&$args;
fastcgi_pass php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout <PHP_TIMEOUT>;
}
This configuration is better, but still has a flaw. If the requested URI ends with .php
and there is no corresponding PHP file in the /app/public
directory, the $original_uri
variable won't be initialized and the _url
query argument would be passed to backend as an empty string:
/some/path
=> /index.php?_url=/some/path
/some/path.php
=> /index.php?_url=
This could be ok for some web applications (empty _url
query argument always meaning an invalid route), but what do we have to do if we want to get an original URI whatever it is? We can achieve it with the help of the map
directive (an extremely powerful nginx feature). However all map
blocks should be declared outside the server
blocks, so we would need an additional file:
/opt/docker/etc/nginx/conf.d/10-map.conf
map $_uri $original_uri {
"" $uri;
default $_uri;
}
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
location / {
try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
set $_uri $uri;
rewrite ^ $uri.php last;
}
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
location ~ \.php$ {
try_files $uri /<DOCUMENT_INDEX>?_url=$original_uri&$args;
fastcgi_pass php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout <PHP_TIMEOUT>;
}
This map
block means that the $original_uri
variable would be equal to $uri
one if it wasn't modified ($_uri
variable isn't initialized and empty). If the $_uri
variable is not empty it means that the original $uri
was modified and the $_uri
variable now keeps its original value, so the value of the $original_uri
variable would be set to $_uri
. This configuration should work with any requests preserving original URI as _url
query argument.
这篇关于webdevops nginx-从网址中删除.php要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!