搜索
当前位置:首页 > 娱乐 > nginx php伪静态

nginx php伪静态

发表于 2026-10-17 02:17:47 来源:烟消火灭网

去年帮朋友处理一个 WordPress 站点迁移,伪静服务器从 Apache 换到了 Nginx,伪静结果所有文章页全挂了 404。伪静后台能进,伪静首页正常,伪静就 permalink 带 .html 后缀的伪静页面一个都打不开。他问我是伪静不是数据库炸了,我说不是伪静,是伪静 Nginx 不认识 PHP 伪静态。

这事其实挺典型。伪静Apache 时代有 .htaccess 文件,伪静mod_rewrite 一开,伪静WordPress 自己写的伪静规则就能跑。Nginx 不吃这套,伪静它没有分布式配置文件的伪静概念,所有 rewrite 必须写在站点配置里,而且语法完全是另一套。很多人第一次碰 Nginx 伪静态,就是卡在这个思维转换上。

伪静态到底伪在哪

先把这个概念捋清楚。伪静态不是说页面真的是静态 HTML 文件,而是 URL 看起来像静态页,实际还是 PHP 动态生成。比如 /article/123.html 这种地址,服务器收到请求后并不会去找一个叫 123.html 的文件,而是把请求转给 index.php,附带参数 ?id=123。用户看到的是 .html 结尾,搜索引擎也更容易收录,但背后跑的还是 PHP。

Nginx 实现这个靠的是 rewrite 指令和 try_files。rewrite 负责改写 URI,try_files 负责兜底——当请求的文件不存在时,交给谁处理。两者配合才能让伪静态规则既生效又不影响真实的静态资源。

一个真实的配置案例

拿最常见的 WordPress 来说,Nginx 站点配置里通常要加这么一段:

location / {  try_files $uri $uri/ /index.php?$args; }

这行看着简单,但坑不少。$uri 先检查请求路径对应的文件是否存在,$uri/ 检查目录,都不存在就把请求扔给 index.php,同时把原始查询参数带上。很多教程只写 /index.php 不带 ?$args,结果分页、搜索参数全丢,页面内容对不上。

如果是自定义的伪静态规则,比如把 /product/123 映射到 /product.php?id=123,那就得用 rewrite:

rewrite ^/product/([0-9]+)$ /product.php?id=$1 last;

这里 last 标记很重要,它表示重写后重新匹配 location。用 break 的话就不会再走一遍 location 匹配,有时候会导致 PHP 文件不被正确解析。我见过有人把 last 写成 break,然后 PHP 文件被当纯文本下载下来,源码全暴露了。

PHP 处理那块别漏了

伪静态规则写对了,但 PHP 没配好照样白搭。Nginx 本身不解析 PHP,得靠 FastCGI 转发给 php-fpm。典型配置长这样:

location ~ \.php$ {  fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }

重点在 SCRIPT_FILENAME 这行。如果路径拼错了,php-fpm 会报 “Primary script unknown”,日志里一堆这种错误。很多人复制网上的配置,$document_root 没改成自己的实际路径,或者 root 指令写在了 location 里面导致变量取不到值。

还有个细节:fastcgi_param 里的 PATH_INFO 有时也需要配。特别是用 /index.php/123 这种形式的伪静态时,不传 PATH_INFO 的话 PHP 拿不到后面的路径信息。不过现在主流框架大多用 query string 模式,这个问题碰到的概率小了些。

调试的时候看日志

伪静态不生效,第一件事是看 Nginx 的 error.log。rewrite 规则写错通常会有 “rewrite or internal redirection cycle” 的报错,意思是重写循环了。比如你把所有请求都重写到 index.php,但 index.php 本身也匹配了规则,就会无限循环。加个 if (!-f $request_filename) 判断能避免大部分循环问题,不过 Nginx 官方不太推荐在 location 里用 if,能靠 try_files 解决就尽量别用。

另一个常见问题是中文 URL。rewrite 规则里的正则如果没处理编码,带中文的伪静态链接会 404。Nginx 默认按字节匹配,中文会被转成 %XX 形式,正则里得用 [^/]+ 这种宽松匹配,别写死字母数字。

我自己的习惯是先在本地用 curl 测试,curl -I 看返回码,再逐步加 rewrite 规则。比直接改生产环境配置然后刷新浏览器靠谱得多。毕竟 Nginx reload 虽然不中断连接,但配置写错导致 500 的时候,排查起来也够烦的。

随机为您推荐
友情链接
版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright © 2016 Powered by nginx php伪静态,烟消火灭网   sitemap

回顶部