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

Nginx中WordPress固定链接与无后缀PHP路由共存失效问题

解决WordPress固定链接与无后缀PHP页面共存的问题

首先得说清楚你遇到的问题根源:你加的那个if (!-e $request_filename)规则优先级太高了!当你访问/resume时,因为这个路径本身不是一个存在的文件或目录,Nginx直接触发了这个if里的rewrite,把请求扔给WordPress的index.php处理,根本没机会走到你定义的@extensionless-php规则去尝试转成resume.php,而WordPress里又没有对应/resume的页面,自然就返回404了。

下面给你两种解决方案,优先推荐第一种通用方案,适合多个无后缀PHP页面的场景;第二种是快速临时方案,适合只有/resume这一个页面的情况。

方案一:重构Nginx配置,用try_files替代if规则(最优)

Nginx里尽量少用if,尤其是在server块下的if,很容易引发优先级问题。我们可以通过调整规则顺序,让无后缀PHP的处理逻辑先于WordPress的固定链接逻辑,同时保留两者的功能。修改后的server块配置如下:

server {
    ...
    root /var/www/html;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name mydomain.com;

    # 优先处理无后缀PHP请求,同时兼顾静态文件和目录
    location / {
        try_files $uri $uri/ @extensionless-php;
    }

    # 处理PHP文件请求,同时实现访问.php后缀时重定向到无后缀URL(满足你的需求)
    location ~* \.php$ {
        # 如果请求URL带.php后缀,301重定向到去掉后缀的版本
        if ($request_uri ~* ^(.+)\.php$) {
            return 301 $1;
        }
        try_files $uri =404;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    # 无后缀转PHP的逻辑,转完后如果文件存在就处理,不存在则交给WordPress
    location @extensionless-php {
        rewrite ^(.*)$ $1.php last;
        try_files $uri.php $uri/index.php @wordpress;
    }

    # WordPress固定链接处理逻辑,所有找不到的请求都扔给index.php
    location @wordpress {
        rewrite ^ /index.php last;
    }
}

配置说明:

  • 移除了原有的server块下的if规则:改用@wordpress location专门处理WordPress的固定链接,避免优先级冲突。
  • 请求处理顺序:
    • 先尝试访问实际存在的文件/目录(比如静态资源、已存在的PHP文件)
    • 找不到的话,进入@extensionless-php尝试转成.php文件,如果转后文件存在(比如/resume转成/resume.php),就交给PHP-FPM处理
    • 如果转成.php后还是不存在,再进入@wordpress规则,把请求扔给WordPress的index.php处理固定链接
  • PHP后缀重定向:新增的location ~* \.php$规则会把所有带.php后缀的请求(比如/resume.php)301重定向到无后缀版本,完美满足你“URL始终不显示.pdf或.php后缀”的要求。

方案二:给/resume单独添加location规则(快速临时方案)

如果只有/resume这一个无后缀PHP页面需要处理,你可以在原配置的location /之前添加一个专门的location规则,让Nginx优先匹配这个请求:

server {
    ...
    root /var/www/html;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name mydomain.com;

    # 专门处理/resume请求,优先匹配
    location /resume {
        try_files $uri $uri.php =404;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    # 原有的WordPress固定链接规则
    if (!-e $request_filename) {
        rewrite ^.*$ /index.php last;
    }

    location / {
        try_files $uri $uri/ @extensionless-php;
    }

    location ~ \.php$ {
        try_files $uri =404;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    location @extensionless-php {
        rewrite ^(.*)$ $1.php last;
    }
}

这个方法的原理是Nginx会优先匹配更具体的location规则,所以访问/resume时会直接走这个专门的规则,转成/resume.php处理,不会被后面的if规则拦截。

最后操作步骤

不管用哪种方案,修改完配置后都要做这两步:

  1. 测试Nginx配置是否合法:
    sudo nginx -t
    
  2. 重启Nginx生效:
    sudo systemctl restart nginx
    

另外,确保WordPress后台的固定链接设置是正确的(比如设置为“帖子名称”模式)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:38:17