
本文详解如何在 Nginx 中通过 rewrite 规则将用户访问的 URL(如 /en/index.php)映射到服务器上真实存在的、位置不同的 PHP 文件(如 /index.php),无需物理创建多语言子目录,支持灵活的语言参数传递与路由抽象。
本文详解如何在 nginx 中通过 rewrite 规则将用户访问的 url(如 `/en/index.php`)映射到服务器上真实存在的、位置不同的 php 文件(如 `/index.php`),无需物理创建多语言子目录,支持灵活的语言参数传递与路由抽象。
在现代 Web 开发中,常需将语义化 URL(如 https://example.com/en/home 或 https://example.com/zh/about)与底层文件系统路径分离——既提升 SEO 与用户体验,又避免冗余文件结构。Nginx 本身不支持 .htaccess 式的动态重写,但其强大的 rewrite 指令配合正则表达式,可高效实现 URL 虚拟化(URL-to-file 路由解耦)。
✅ 核心原理:URL 是逻辑视图,文件路径是物理实体
Nginx 的 rewrite 指令在请求处理早期阶段对 URI 进行内部重写(非 301/302 重定向),修改 $request_uri 后继续匹配 location 块。关键在于:所有 URL 都是“虚拟”的,而最终执行的 PHP 文件路径必须真实存在且可被 fastcgi_pass 正确转发。
? 基础配置示例:提取语言代码并透传为查询参数
假设你希望用户访问 /en/index.php 时,实际执行根目录下的 /index.php,并将语言标识 en 作为 lang 参数注入:
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php;
# 关键:将 /{lang}/index.php 重写为 /index.php?lang={lang}
location ~ ^/([a-z]{2})/index\.php$ {
rewrite ^/([a-z]{2})/index\.php$ /index.php?lang=$1 last;
}
# 处理 PHP 请求(保持原有 fastcgi 配置)
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}
}✅ 效果说明:
立即学习“PHP免费学习笔记(深入)”;
- 访问 https://example.com/en/index.php → Nginx 内部重写为 /index.php?lang=en → 执行 /var/www/html/index.php
- $_GET['lang'] 在 PHP 中可直接获取值 "en",用于动态加载语言包或模板
? 更灵活的通用模式:支持任意子路径与参数保留
若需支持 /zh/contact.php、/ja/blog/article123.php 等形式,推荐使用更健壮的捕获组:
# 匹配 /{lang}/{any-path}.php,并重写为 /{any-path}.php?lang={lang}
rewrite ^/([a-z]{2})/(.+\.php)$ /$2?lang=$1&$args last;⚠️ 注意事项:
- $args 用于保留原始查询参数(如 /en/page.php?id=5 → /page.php?lang=en&id=5);
- last 表示重写后重新匹配 location,确保 PHP 处理块仍生效;用 break 则终止重写但不重新匹配(慎用);
- 正则中 ([a-z]{2}) 限制语言码为两位小写字母,可根据需要扩展为 ([a-z]{2,3}(-[a-z]{2})?) 以支持 zh-CN;
- 务必确保 root 和 index.php 物理路径正确,rewrite 不改变文件查找根目录;
- 修改配置后执行 sudo nginx -t && sudo systemctl reload nginx 生效。
? 进阶建议:结合 PHP 路由统一处理
与其为每个 URL 编写 rewrite 规则,更推荐「前端控制器」模式:
- 将所有 PHP 请求(含带语言前缀的)统一重写至单一入口(如 index.php);
- 在 PHP 中解析 $_SERVER['REQUEST_URI'] 提取语言与路由,再分发逻辑。
示例 rewrite:# 所有 /{lang}/* 请求均交由 index.php 统一处理 rewrite ^/([a-z]{2})/(.*)$ /index.php?lang=$1&path=$2 last;PHP 端即可通过 $_GET['lang'] 和 $_GET['path'] 实现完全动态的国际化路由。
总结:Nginx 的 rewrite 是实现 URL 抽象的核心能力,它让开发者摆脱文件系统约束,构建语义清晰、易于维护的 Web 架构。合理设计正则与参数传递策略,配合 PHP 层逻辑,即可轻松支撑多语言、多版本、RESTful 等复杂路由场景。











