伪静态生效的最直接验证方式是访问不带index.php的URL(如http://example.com/index/hello)能正常响应且地址栏无index.php;若返回404、跳转或仍显示index.php,则配置未生效,需检查服务器重写规则、框架路由开关及缓存。

访问不带index.php的URL是否返回正常页面
这是最直接的验证方式。伪静态生效后,http://example.com/index/hello 应该能正确触发 IndexController 的 hello 方法,而不是返回 404 或跳转到 index.php/index/hello。
注意:不要只测根路径(如 /),要测至少一个带路由参数的真实路径,比如 /article/123 或 /user/profile —— 这些路径必须在框架中定义过路由规则,否则即使伪静态转发成功,也会因路由未匹配而 404。
- 如果浏览器地址栏仍显示
index.php/xxx,说明重写未生效或被浏览器缓存,先清空缓存或用隐身模式重试 - 如果返回空白页且 HTTP 状态码是 500,问题不在伪静态转发,而在框架初始化阶段(见下一条)
- 如果返回下载
index.php文件,说明 Nginx/Apache 没把请求交给 PHP 解析器,而是当静态文件处理了
检查 $_SERVER 变量是否拿到原始路径信息
在 index.php 开头插入一行调试代码:die(var_dump($_SERVER['PATH_INFO'] ?? $_GET['s'] ?? 'MISSING'));,然后访问一个伪静态 URL(如 /test/abc)。
不同配置下应看到:
立即学习“PHP免费学习笔记(深入)”;
- Apache +
index.php/$1规则 → 输出类似/test/abc(即PATH_INFO有值) - Nginx +
/index.php?s=$1规则 → 输出类似/test/abc(即$_GET['s']有值) - 输出
MISSING或空字符串 → 说明服务器根本没传路径信息,重写规则形同虚设
别依赖 phpinfo() 查看,它只反映 PHP 配置,不反映本次请求实际收到的 $_SERVER 值。
查看 Web 服务器错误日志定位静默失败
很多伪静态问题不会报错页面,但会在日志里留下线索。Apache 和 Nginx 默认都记录访问和错误日志,这是最可靠的排查依据。
- Apache 日志路径通常是
/var/log/apache2/error.log(Debian/Ubuntu)或/usr/local/apache/logs/error_log(Mac/WAMP);搜索关键词rewrite、.htaccess、deny - Nginx 日志默认在
/var/log/nginx/error.log;重点关注rewrite or internal redirection cycle(重定向循环)、no such file or directory(路径拼错)、FastCGI sent in stderr(PHP 层崩溃) - 宝塔用户可直接在面板【网站】→【日志】里查看对应站点的 Nginx 错误日志,无需 SSH
特别注意:Nginx 的 if 指令在某些版本中会静默忽略语法错误,只在 error.log 里记一条 warn,不报 500 却始终不生效。
确认框架路由开关和基础配置已启用
伪静态只是把请求“送进来”,最终能否解析,取决于 ThinkPHP 自身是否准备好接招。
- TP5:检查
config/app.php中'url_route_on' => true是否开启;TP6:确认config/app.php中'route_enable' => true - TP5 默认依赖
PATH_INFO,若你用了s=参数模式,需确保'url_common_param' => false(否则框架会忽略s) - TP6 若启用了
'url_route_must' => true,所有访问路径必须显式注册,未注册的哪怕转发成功也返回 404 - 运行
php think route:list(TP6)或php index.php route:list(TP5)确认路由表非空,且目标路径出现在列表中
最容易被忽略的是:框架配置修改后,TP5 的 runtime 缓存可能未清除,TP6 的 route 缓存也可能未刷新 —— 改完配置记得删掉 runtime/cache/ 和 runtime/route/ 目录再试。



















