我需要创建一个我无法测试的 API网关 ...但问题是关于管理PHP脚本。
my1
和issn
的特殊名称在2018端口重定向到localhost my2
和my3
的特殊名称重定向到ETC.php
Pseudocode详情为“我需要什么”,
if ($uri exists) {
if extension is .php use it with php7.0-fpm.sock
else use it as static page;
} else
try the @proxy_rewrite_engine;
@proxy_rewrite_engine =
if (regex ^\(my[23])$ use
ETC.php;
elseif (regex ^/(\d+)/my1$ use
http://127.0.0.1:2018?type=int&val=$1
elseif ^/([0-9]+\-\d+[Xx]?)/issn$ use
http://127.0.0.1:2018?type=str&val=$1
else
say error;
我有问题的解决方案,请展示一个真正的解决方案,将“说明”部分翻译成具体和正确的NGINX脚本代码。
...下面,我的错误 - NGINX脚本提供线索和灵感,这不是解决方案......需要使用if
而不是location
吗? fastcgi_param
有效吗?我可以将地点分组吗?
server {
server_name test.mytest.news;
root /var/www/test;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ @proxy;
}
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi.conf; # without SCRIPT_FILENAME
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location @proxy {
rewrite ^\?(my[23])$ $document_root/ETC.php?cmd=$1
last;
rewrite ^/(\d+)/my1$ ?type=int&val=$1
break;
rewrite ^/([0-9]+\-\d+[Xx]?)/issn$ ?type=str&val=$1
break;
proxy_pass http://127.0.0.1:2018;
}
include snippets/ssl-test.mytest.news.conf;
} #end server
注意@cnst评论:假设我在说“所有文件HTML或PHP” = 时需要try_files
必须尝试其他文件tham index.htm,可以是文件夹,图像和其他文件。
答案 0 :(得分:3)
如果希望“脚本100%可靠,通过构建(而不是通过测试)”,那么将多个独立问题放在一个问题中可能不是最好的方法。 / p>
在将请求传递给单独的后端之前必须检查文件是否存在的理由并不完全清楚,特别是如果请求与给定的正则表达式匹配,例如issn$
。最好的方法是对案件的每个不同处理使用单独的location
指令。
更具体地说,您的方法也存在以下错误:rewrite ^\?(my[23])$
中的正则表达式不太可能匹配任何请求,因为所有外部请求都以斜杠开头。
同样,根据https://serverfault.com/a/864778/110020,rewrite ^/(\d+)/my1$ ?type=int&val=$1
中的替换字符串不太可能正确;事实上,当我尝试上面的代码时,根据500 Internal Server Error
,我得到的是nginx/error.log
:
2017/07/24 08:46:22 [error] 45776#0: *2 the rewritten URI has a zero length, client: 127.0.0.1, server: , request: "GET /44444/my1 HTTP/1.1", host: "localhost:
这是因为您确实将URI重写为空的 - 问号?
及其后的任何内容,在nginx中的请求处理中通常不是URI的一部分,因此,URI确实是空的。解决方案:至少在?
前面放一个斜杠(即/?id=
),或者更好的是,必须激活脚本的全名(特别是因为这只是一个内部重定向)
答案 1 :(得分:0)
Nginx适用于大型配置。糟糕的主意是优化nginx.conf。 做起来很简单,它会努力工作:) 我认为像这样的配置可以正常工作:
# Try to load existing files
location / {
try_files $uri $uri/ @rewriteIt;
}
# Handle all requests except two other locations below
location @rewriteIt {
# Send it to index.php
rewrite ^(.*)$ /index.php?cmd=$1 last;
}
# This RegExp location will rewrite to ETC.php
# It is more priority, than "/" and @rewriteIt
location ~ ^(my2|my3) $ {
rewrite ^(.*)$ /ETC.php?cmd=$1 last;
include /etc/nginx/fastcgi.conf; # without SCRIPT_FILENAME
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
# This RegExp location will proxy to 2018 port
# It is more priority, than "/" and @rewriteIt
location ~ ^(my1|issn) $ {
proxy_pass http://127.0.0.1:2018;
}
# This location handles all php files to php-fpm
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi.conf; # without SCRIPT_FILENAME
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}