You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGINX路径重写配置问题:兼容POST请求的Symfony旧API URL改写

Symfony遗留API的NGINX内部URL重写配置方案

问题背景

维护的Symfony(2.8升级至3.4)遗留API有两个入口文件:app_dev.php(仅开发环境使用)和app.php(生产环境入口),但生产环境中仍有外部应用通过https://domain/app_dev.php/the/path访问。需要内部改写URL(不能用301重定向,避免丢失POST请求数据),将这类请求转发到https://domain/app.php/the/path或更简洁的https://domain/the/path。

此前尝试添加rewrite /app_dev\.php/(.*) /app.php$1 break;等规则返回500错误;修改location匹配为^/(app|app_dev)\.php(/|$)虽能运行,但未实现路径重写的需求。


解决方案

方案1:将app_dev.php请求内部转发到app.php

在php-prod.conf的server块中,新增专门匹配app_dev.php的location规则,内部改写请求路径并复用原app.php的PHP-FPM配置:

## php-prod.conf 修改后的完整server块
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;
    }

    # 新增:匹配app_dev.php请求,内部转发到app.php
    location ~ ^/app_dev\.php(/|$) {
        # 复用OPTIONS请求处理逻辑
        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;
        }

        # 内部改写路径:替换app_dev.php为app.php
        rewrite ^/app_dev\.php(/.*)$ /app.php$1 break;
        # 转发到PHP-FPM,复用原app.php的fastcgi配置
        fastcgi_pass php;
        fastcgi_read_timeout 3600;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
    }

    location / {
        try_files               $uri /app.php$is_args$args;
    }

    # 保留原app.php的生产环境配置
    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;

        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;

        internal;
    }

    # 拦截其他未授权的PHP文件请求
    location ~ \.php$ {
        return 404;
    }

    error_log /var/log/nginx/error.log;
    access_log off;
}

方案2:直接改写为无入口文件的干净路径(推荐)

如果希望直接去掉入口文件,将https://domain/app_dev.php/the/path改写为https://domain/the/path,只需修改location /块的逻辑:

## php-prod.conf 修改后的location /块
location / {
    # 优先处理app_dev.php开头的请求,去掉入口文件路径
    rewrite ^/app_dev\.php(/.*)$ $1 break;
    # 执行原有的静态文件匹配和入口转发逻辑
    try_files $uri /app.php$is_args$args;
}

# 保留原app.php和其他location配置不变

此前尝试报错原因

之前添加rewrite规则返回500的核心原因:

  • 原配置中location ~ \.php$会拦截所有未被^/app\.php匹配的PHP文件请求,直接返回404;
  • 当rewrite后的请求仍携带.php后缀时,会被该规则拦截,或触发fastcgi配置中的路径解析错误;
  • 新增专门的location ~ ^/app_dev\.php(/|$)可以优先匹配请求,避免被404规则拦截,同时直接复用合法的fastcgi配置处理改写后的请求。

内容的提问来源于stack exchange,提问作者Alex Bailey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:57:35