nginx博客伪静态核心是将动态url(如/post.php?id=123)重写为静态路径(如/post/123.html),通过rewrite捕获id映射到php入口,配合try_files或if判断避开真实文件,并用last标志确保重写后重新匹配location以正确转发至php处理器。

博客系统做伪静态,核心是把带参数的动态 URL(比如 /post.php?id=123)转成干净的路径形式(比如 /post/123.html),Nginx 本身不执行 PHP,只负责把请求“转发”给后端脚本,所以重写规则要精准、不干扰静态资源,还得避开真实存在的文件。
基础 rewrite 规则写法
最常用的是捕获数字 ID 并映射到 PHP 入口:
-
匹配
/post/123.html→ 转给/post.php?id=123:rewrite ^/post/(\d+)\.html$ /post.php?id=$1 last; -
匹配
/category/webdev→ 转给/category.php?name=webdev:rewrite ^/category/([^/]+)$ /category.php?name=$1 last; - 注意
last表示重写后重新进入 location 匹配流程,确保能走到 proxy_pass 或 fastcgi_pass;别用break,否则可能无法正确传递给 PHP 处理器。
避免误伤真实文件
如果博客里有真实存在的 /css/style.css 或 /uploads/avatar.jpg,直接写全局 rewrite 会把它们也重写,导致资源加载失败。推荐用 try_files + 条件判断组合:
- 先查文件是否存在,存在就直接返回,不存在再交给 PHP 处理:
location / {<br> try_files $uri $uri/ /index.php?$query_string;<br>} - 或者用 if 判断(不推荐高频使用,但简单场景可用):
if (!-e $request_filename) {<br> rewrite ^(.*)$ /index.php?s=$1 last;<br>}
(适用于 ThinkPHP/Laravel 类路由入口模式)
适配常见博客程序结构
不同博客框架入口和参数习惯不同,规则得跟着调:
-
Typecho / WordPress(固定链接设为
/archives/123.html):rewrite ^/archives/(\d+)\.html$ /index.php/archives/$1 last; -
基于 index.php 的单入口(如部分静态生成+动态回退):
rewrite ^/([a-zA-Z0-9_-]+)/?$ /index.php?slug=$1 last; -
多级分类支持(如
/tech/linux/command.html):rewrite ^/([a-z]+)/([a-z]+)/([a-z]+)\.html$ /article.php?cat=$1&sub=$2&id=$3 last;
调试与验证要点
配完别急着 reload,先确认几件事:
- 正则是否过度匹配?比如
^/post/.*$会吃掉所有/post/开头的请求,包括/post/css/main.css—— 应该写成^/post/(\d+)\.html$更精确 - 检查 Nginx 错误日志:
tail -f /var/log/nginx/error.log,常见报错如 “No input file specified” 说明 PHP-FPM 没收到正确 SCRIPT_FILENAME - 用
curl -I http://yoursite/post/123.html看返回状态码,200 才算成功;如果是 301/302,说明误用了redirect或permanent - 确保
location ~ \.php$ { ... }块存在且 fastcgi_pass 指向正确,否则 rewrite 过去也没人处理











