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规则:改用
@wordpresslocation专门处理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规则拦截。
最后操作步骤
不管用哪种方案,修改完配置后都要做这两步:
- 测试Nginx配置是否合法:
sudo nginx -t - 重启Nginx生效:
sudo systemctl restart nginx
另外,确保WordPress后台的固定链接设置是正确的(比如设置为“帖子名称”模式)。
内容的提问来源于stack exchange,提问作者xcdfv
相关产品推荐
相关产品推荐

