如何使用 NGINX 重寫 URL 以將 index.php 隱藏在頻繁更改的多個子文件夾中?
所以我們有一個 PHP 開發伺服器,其中每個開發人員都有一個個人子域,例如https://dev-abc.mysite.com和相應的 NGINX 配置。
開發人員將我們的 repo 的一個分支檢出到這樣的文件夾中:
- /var/www/html/dev-abc/branch-X
- /var/www/html/dev-abc/branch-Y
- /var/www/html/dev-abc/branch-Z
URL 模式:
https ://dev-abc.mysite.com/{BRANCH}/index.php/{MODULE}/{CLASS}/?event={EVENT}&otherParamX=Y
{MODULE} 是模組中的文件夾/
{CLASS} 是模組中的類文件/{MODULE}
{EVENT} 是模組中的類中的方法/{MODULE}
像這樣訪問分支: https ://dev-abc.mysite.com/branch-X/index.php/report/invoice
我們只是嘗試將 URL 重寫為:
https ://dev-abc.mysite.com/branch-X/report/invoice/
對於其子域下的所有子目錄。
NGINX 配置如下所示:
路徑:
/etc/nginx/conf.d/dev-abc.conf
server { server_tokens off; listen 80; autoindex off; server_name dev-abc.mysite.com; root /var/www/html/dev-a; error_log /home/dev-abc/nginx-error.log notice; include /etc/nginx/includes/dev_sandbox; rewrite_log on; }
注意:/etc/nginx/includes/dev_sandbox 包含很多用於標頭和 CORS 的內容,因此除非需要,否則我不會發布它,因為它很長。
我嘗試了以下方法:
嘗試1:
location / { try_files $uri $uri/ /index.php$is_args$args; }
NGINX 拋出:^(.+.php)(/.+)" 與 “/index.php” 不匹配 在瀏覽器中也得到 “File not found”
嘗試2:
location ~(.+)/(.+) { try_files $uri $1/index.php/$2; }
作品:
https ://dev-abc.mysite.com/branch-X/report/
不起作用:
https ://dev-abc.mysite.com/branch-X/report/invoice/
嘗試 3:
location ~(.+)/(.+)/(.+) { try_files $uri $1/control.php/$2/$3; }
作品:
https ://dev-abc.mysite.com/branch-X/report/invoice/
不起作用:
https ://dev-abc.mysite.com/branch-X/report/
拋出:
“/var/www/html/dev-abc/branch-X/report/index.php”未找到
重複運營商喜歡
*
並且+
是貪婪的。因此,第一次擷取(.+)/(.+)
將獲取所有內容,直到最後一次/
(至少有一個字元跟隨它)。因此,您的嘗試 2的行為完全是意料之中的。您可以改用惰性重複運算符,例如
*?
and+?
,例如:location ~ (.+?)/(.+) { ... }
或者,您可以使用僅匹配不匹配的字元的字元類
/
(請記住,第一個字元始終是 a/
),例如:location ~ (/[^/]+)/(.+) { ... }
雖然在這種情況下不是絕對必要的,但您可能應該在表達式周圍添加錨點,因為您只對匹配整個 URI 感興趣,例如:
location ~ ^(.+?)/(.+)$ { ... }
或者:
location ~ ^(/[^/]+)/(.+)$ { ... }
重要的提示
正則表達式位置塊按順序求值,直到找到匹配項。確保您的
location ^(.+.php)(/.+)
塊按順序首先出現,以避免重定向循環。