nginx可通过try_files或rewrite实现隐藏入口脚本,如将/index.php/article/123重写为/article/123,需配合fastcgi_split_path_info解析path_info,并避免301跳转以保持url简洁。

在 Nginx 中,可以通过 rewrite 指令配合 location 块,将带入口脚本(如 index.php、app.php)的 URL 重写为更简洁、无脚本名的路径,实现“隐藏入口脚本”的效果。核心思路是:让 Nginx 在内部将请求路径补全为真实可处理的脚本路径,同时对外保持 URL 不变(即 内部重写,非外部跳转)。
1. 理解常见场景:比如隐藏 index.php
典型需求是把 https://example.com/index.php/article/123 变成 https://example.com/article/123,且 PHP 应用仍能正确接收 $_SERVER['REQUEST_URI'] 或路由参数。
关键点:
- 不能用
return 301—— 那是外部重定向,URL 会暴露脚本名; - 要用
rewrite ... last或直接在location ~ \.php$前匹配并重写; - 最终请求必须能落到 PHP-FPM 处理(如通过
fastcgi_pass)。
2. 推荐配置方式(以 Laravel / ThinkPHP 类框架为例)
假设项目入口是 public/index.php,所有请求应由它统一处理。Nginx 配置示例如下:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
这段配置本身不显式用 rewrite,但它是更高效、更安全的替代方案:优先尝试静态文件,找不到则内部转发到 /index.php 并携带原始查询参数。这是官方推荐做法,比反复 rewrite 更清晰。
如果确实需要显式 rewrite(比如兼容旧规则或特殊路径逻辑),可写:
location / {
rewrite ^/(.*)$ /index.php?/$1 last;
}
注意:last 表示内部重发,Nginx 会重新匹配 location;break 则停止 rewrite,直接执行当前 block 内容。
3. 配合 PHP 正确解析 PATH_INFO
隐藏脚本名后,PHP 要能从 $_SERVER['PATH_INFO'] 或 $_SERVER['REQUEST_URI'] 中提取路由信息。需确保:
- FastCGI 参数中启用 PATH_INFO 支持(常见于 Laravel 等框架要求):
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param PATH_INFO $realpath_root$fastcgi_path_info;
并在 location 中启用 path_info 解析:
location ~ ^(.+\.php)(/.*)?$ {
alias /var/www/html/public$1;
fastcgi_pass php-fpm;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PATH_INFO $realpath_root$fastcgi_path_info;
}
其中 fastcgi_split_path_info 是关键——它让 Nginx 能把 /index.php/admin/user 拆成脚本部分和 path info 部分。
4. 验证与调试技巧
配置完成后,检查是否生效:
- 访问
/about,查看响应是否来自index.php(可通过加一行var_dump($_SERVER['REQUEST_URI']);验证); - 检查 Nginx 错误日志:
tail -f /var/log/nginx/error.log,rewrite 循环或 404 通常在这里暴露; - 用
curl -I http://localhost/about确认状态码是 200 而非 301/302; - 避免 rewrite 循环:确保 rewrite 目标不再匹配原规则(如加前缀、限定 location 范围)。
不复杂但容易忽略。











