我目前正在开发一个在旧 Symfony 版本上运行的旧版 API(2.8 正在升级到 3.4)。
该应用程序有两个“主要”PHP 入口点:app_dev.php 和 app.php。 _dev 端点仅应在开发环境中使用,但在旧的生产应用程序中使用不正确。
我们可以轻松修改 API 以避免暴露此文件(并且已经成功完成),但是,我们无法轻松更新连接到 API 的某些应用程序。例如,某些应用程序仍在尝试使用 https://domain/app_dev.php/the/path 进行连接。
作为临时解决方案,在我们努力修复使用 API 的应用程序时,我们希望将 https://domain/app_dev.php/the/path 重写为 https://domain/app.php/the/path 或者更好的是 https://domain/the/path。 我们相信重写是正确的选择,但也许我们不正确?
我们有 NGINX 的当前配置:
## nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
}
http {
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# log_format must come before access_log!
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status '
'$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
client_max_body_size 50M;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
include /etc/nginx/conf.d/*.conf;
}
## php-prod.conf
upstream php {
server 127.0.0.1:9000;
}
server {
listen 80;
client_max_body_size 50M;
client_body_buffer_size 128k;
fastcgi_param REMOTE_USER $remote_user;
root /var/www/web;
location = /favicon.ico {
break;
}
location / {
try_files $uri /app.php$is_args$args;
}
# Configuration for PHP passthrough on remote / production endpoints
location ~ ^/app\.php(/|$) {
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
add_header Access-Control-Allow-Headers "x-custom-auth, content-type, x-requested-with, authorization, mobile";
add_header Access-Control-Allow-Methods "POST, PUT, PATCH, GET, DELETE";
add_header Access-Control-Allow-Origin "$http_origin";
add_header Access-Control-Max-Age 1728000;
return 204;
}
fastcgi_pass php;
fastcgi_read_timeout 3600;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the current version of your application, you
# should pass the real application path instead of the path to the symlink to PHP FPM. Otherwise, PHP's OPcache
# may not properly detect changes to your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404: http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
# Return 404 for all other php files not matching the front controller.
# This prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/error.log;
access_log off;
}
我尝试将 rewrite /app_dev\.php/(.*) /app.php$1 break; 添加到各个地方,包括主 server 块和 location / 块和似乎无法使重定向正常工作。我尝试过使用 break 和 last 但我只从 API 收到没有内容的 500 响应。
如果我更新 location ~ ^/app\.php(/|$) { 到 location ~ ^/(app|app_dev)\.php(/|$) { 它可以正常工作,所以我知道 API 在 NGINX 背后“工作”。
我应该提到 301 重定向在这里不起作用,因为我还需要重写 POST 请求。然而,我已经将其作为 301 重定向进行了测试,并且得到了预期的结果(但 301 不适用于我们的 POST 请求):
location / {
rewrite /app_dev\.php/(.*) /$1 permanent;
try_files $uri /app.php$is_args$args;
}
...
127.0.0.1 - testCommand [25/May/2023:09:04:31 +0000] "POST /app_dev.php/api/path HTTP/1.0" 301 162 "-" "PostmanRuntime/7.32.2"
172.20.0.1 - testCommand [25/May/2023:09:04:31 +0000] "POST /app_dev.php/api/path HTTP/1.1" 301 162 "-" "PostmanRuntime/7.32.2" "-"
172.20.0.1 - - [25/May/2023:09:04:31 +0000] "GET /api/path HTTP/1.1" 301 162 "https://api.domain.com/app_dev.php/api/path" "PostmanRuntime/7.32.2"
如果我将其设置为中断:
172.20.0.1 - testCommand [25/May/2023:09:08:05 +0000] "POST /app_dev.php/api/path HTTP/1.1" 500 5 "-" "PostmanRuntime/7.32.2" "-" 127.0.0.1 - testCommand [25/May/2023:09:08:05 +0000] "POST /app_dev.php/api/path HTTP/1.0" 500 0 "-" "PostmanRuntime/7.32.2"
如果我将其设置为最后:
172.20.0.1 - testCommand [25/May/2023:09:13:57 +0000] "POST /app_dev.php/api/path HTTP/1.1" 500 5 "-" "PostmanRuntime/7.32.2" "-" 127.0.0.1 - testCommand [25/May/2023:09:13:57 +0000] "POST /app_dev.php/api/path HTTP/1.0" 500 0 "-" "PostmanRuntime/7.32.2"
所以我的问题是如何让这个重写工作,将 https://domain/app_dev.php/the/path 等 URL 重写为 https://domain/app.php /the/path 甚至更好 https://domain/the/path?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
您尝试
重写/app_dev\.php/(.*) /app.php$1 break;,但break是错误的标志 - 您需要使用最后强>。请参阅rewrite指令。 p>或者,要重定向 POST 请求,您可以使用 307状态响应,例如:
location ~ ^/app_dev\.php(/|$) { return 307 /app.php$1$is_args$args; }确保将其放置在
location ~ \.php$块上方。我注意到
location ~ ^/app\.php(/|$)块被标记为internal,这会阻止您的服务器响应的外部请求>/app.php。这似乎与您问题中的某些陈述相矛盾。