ThinkPHP在IIS伪静态失败主因是web.config规则缺失PATH_INFO透传、cgi.fix_pathinfo未设为1、或URL重写模块未安装;需配置含HTTP_X_REWRITE_URL注入、文件目录存在性判断及appendQueryString="true"的rewrite规则,并确保php.ini中cgi.fix_pathinfo=1且模块已正确安装启用。

ThinkPHP在IIS上伪静态配不起来,90%不是代码问题,而是web.config没写对、cgi.fix_pathinfo没开、或者URL重写模块根本没装——这三处漏掉任何一项,index.php就永远甩不掉。
web.config规则必须带PATH_INFO转发逻辑
IIS不像Apache能自动把/user/list/id/123拆成PATH_INFO变量传给PHP,它默认只把查询字符串(?xxx)交给php-cgi.exe。所以web.config里不能只写个空壳<match url="^(.*)$"/>,必须显式把原始路径作为QUERY_STRING或环境变量透传过去。
- 确保
<conditions>里检查了文件和目录是否存在,否则静态资源(.js、.css)全被重写到index.php,页面直接白屏 -
<action type="Rewrite" url="index.php" />后面要加appendQueryString="true",否则$_GET为空 - 关键点:用
<set name="HTTP_X_REWRITE_URL" value="{R:0}" />把原始URL塞进$_SERVER['HTTP_X_REWRITE_URL'],ThinkPHP 6+会优先读这个变量还原路由
<rule name="ThinkPHP_Rewrite" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" appendQueryString="true" />
<serverVariables>
<set name="HTTP_X_REWRITE_URL" value="{R:0}" />
</serverVariables>
</rule>
cgi.fix_pathinfo=1 是PATHINFO生效的前提
ThinkPHP依赖$_SERVER['PATH_INFO']解析路由,而IIS+FastCGI默认不生成这个变量。PHP官方明确说明:cgi.fix_pathinfo设为0时,PHP会跳过PATH_INFO提取逻辑,直接报No input file specified或路由全404。
- 打开
php.ini,找到cgi.fix_pathinfo,必须设为1(不是注释掉,是显式赋值) - 改完后重启IIS的
W3SVC服务,仅重启PHP进程无效 - 验证方式:在
index.php开头加var_dump($_SERVER['PATH_INFO'] ?? 'missing');,访问/user/list应输出/user/list而非missing
URL重写模块(URL Rewrite Module)必须手动安装
IIS默认不带重写功能,web.config里的<rewrite>节点会被直接忽略——连错误都不报,静默失效。
立即学习“PHP免费学习笔记(深入)”;
- 去微软官网下载并安装
URL Rewrite Module 2.1(支持IIS 7.5+),不是ISAPI_Rewrite.dll那种老古董 - 安装后,在IIS管理器 → 服务器节点 → “模块”里确认能看到
RewriteModule - 如果站点级别看不到“URL重写”图标,说明模块只装到了服务器层,需在站点根目录右键 → “管理网站” → “高级设置”里确认
enabledModules包含rewrite
ThinkPHP配置要配合IIS行为调整
框架层不改,光靠web.config硬扛,容易在二级目录或子域名下翻车。
-
'url_html_suffix' => ''建议设为空字符串,避免.html后缀干扰IIS路径匹配逻辑 -
'url_route_on' => true必须开启,否则即使重写成功,ThinkPHP也走默认index.php?s=xxx模式 - 入口文件路径要对齐:如果项目部署在
http://site.com/app/,web.config必须放在/app/目录下,且index.php也在同级,不能错位到/app/public/却把web.config放根目录
最常被忽略的是HTTP_X_REWRITE_URL变量——它不是IIS原生支持的,全靠web.config里<set>手动注入,缺了这行,ThinkPHP 6.x 就只能靠$_SERVER['REQUEST_URI']硬凑,而IIS的REQUEST_URI经常被截断或编码异常。



















