Nginx可通过server块中rewrite+if判断实现伪静态,如将/index.php?id=123转为/article/123.html且URL不变;需用if(!-e $request_filename)避免覆盖静态资源,rewrite规则用last标志内部重定向,并支持PATH_INFO统一入口简化配置。
直接在 Nginx 的 server 块中写 rewrite 规则,配合文件存在性判断,就能把 index.php?id=123 这类动态链接转成 /article/123.html 这样的静态外观,浏览器地址栏不变,后端仍走 PHP 处理。
最常用也最稳妥的方式是先检查请求路径是否对应真实文件或目录,不存在时再触发重写:
server 块内添加 location 区块,通常放在 root 和 index 指令之后if (!-e $request_filename) 确保只对非真实资源的请求做重写,避免覆盖 js/css/img 等静态文件^/article/(d+).html$ 匹配 /article/123.html,然后映射到 /index.php?id=$1
last,表示内部重定向,不改变浏览器 URL,且会重新匹配 location假设你的 PHP 入口是 index.php,想让文章页和列表页都呈现 HTML 后缀:
rewrite ^/article/(d+).html$ /index.php?action=article&id=$1 last;
rewrite ^/category/(d+)/page-(d+).html$ /index.php?action=category&cid=$1&page=$2 last;
rewrite ^/page-(d+).html$ /index.php?action=home&page=$1 last;
所有规则都放在同一个 location / { ... } 块里,按顺序匹配,靠前的优先生效。
如果你的 PHP 框架或程序支持 PATH_INFO(如 ThinkPHP、CodeIgniter),可把所有请求集中到一个入口,减少规则数量:
rewrite ^/(.*).html$ /index.php/$1 last;
/user/profile.html 实际执行 index.php/user/profile
$_SERVER['PATH_INFO'] 或框架路由自动解析路径,无需每个链接单独写 rulefastcgi_split_path_info 并正确传递 PATH_INFO规则写完不能直接上线,必须验证是否按预期工作:
nginx -t 检查语法,再 nginx -s reload 生效/article/999.html),看是否返回 PHP 页面而非 404error_log /path/to/error.log notice;),开启 notice 级别可看到 rewrite 执行日志$_GET['id'] 是否拿到值,而不是空或报错