ThinkPHP在IIS伪静态失效主因是URL重写模块未安装或web.config缺少action重写动作及PATHINFO条件判断,需安装URL Rewrite Module 2.1、配置含{R:1}捕获和s=参数的rule,并确保ThinkPHP启用url_model=2。

ThinkPHP 在 IIS 上伪静态失效,90% 是因为 web.config 缺少关键重写逻辑或 URL 重写模块未启用——不是规则写得不对,而是根本没进到 PHP 层。
IIS 必须先装 URL 重写模块(rewrite.dll)
Windows Server 自带的 IIS 默认不包含 URL 重写功能。没有这个模块,web.config 里的 <rewrite> 节点会被完全忽略,连日志都不会报错。
- 去微软官网下载安装 URL Rewrite Module 2.1(支持 IIS 7.5+)
- 安装完必须重启 IIS(不是重启网站,是整个 IIS 服务)
- 打开 IIS 管理器 → 查看左侧“模块”列表里是否有
UrlRewriteModule,没有就说明没生效 - 如果用的是共享主机,无法安装模块,则只能换服务器或改用
index.php显式路径(伪静态不可行)
web.config 的 rule 必须转发请求到 index.php?s=
很多示例只写 <match url="^(.*)$">,但没指定怎么处理匹配到的路径——IIS 不会自动把 /user/list 变成 index.php?s=/user/list,这步必须显式声明。
- 正确写法要在
<rule>内加<action type="Rewrite" url="index.php?s={R:1}" /> -
{R:1}是正则捕获组,对应^(.*)$匹配到的全部路径 - 必须保留
s=参数,ThinkPHP 5/6 的 PATHINFO 模式依赖它解析路由 - 完整示例:
<rule name="ThinkPHP" stopProcessing="true"> <match url="^(.*)$" ignoreCase="false" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="index.php?s={R:1}" /> </rule>
ThinkPHP 配置要和 IIS 规则对齐
IIS 把路径转给 index.php?s=xxx 后,ThinkPHP 还得认得这个格式,否则仍会 404。
立即学习“PHP免费学习笔记(深入)”;
- 确认
config/app.php中'url_model' => 2(PATHINFO 模式) - 不要设
'url_html_suffix' => '.html'后又在 IIS 规则里漏掉.html匹配——除非你真打算所有 URL 都带 .html,否则建议留空 - 如果项目部署在子目录(如
http://site.com/shop/),web.config的url匹配需加前缀,比如^shop/(.*)$,且url="index.php?s=/{R:1}"中的s=值要与实际入口路径一致 - 开发环境用内置 PHP 服务器(
php -S)测试时,IIS 规则完全不生效,别拿它验证伪静态
常见错误现象和快速定位方法
伪静态配置后访问 404 或 500,别急着改规则,先看这几处:
- 访问
http://yourdomain.com/index.php?s=/index/index能正常打开首页?不能 → ThinkPHP 配置或入口文件有问题,和 IIS 无关 - 访问
http://yourdomain.com/abc返回 404,但http://yourdomain.com/index.php/abc正常 → IIS 重写模块没启用或web.config未被读取(检查文件名是否为web.config,不是web.config.txt) - IIS 日志里出现
HTTP 500.52错误 → URL 重写模块内部失败,大概率是<action>的url值写错了路径(比如写成./index.php或绝对路径) - 页面能打开但 CSS/JS 404 →
<conditions>缺失,导致静态资源也被重写到了index.php;必须加上IsFile和IsDirectory判断
真正卡住人的地方,往往不是规则本身,而是 IIS 模块加载状态、web.config 文件编码(必须 UTF-8 无 BOM)、以及 ThinkPHP 的 url_model 和入口路径是否严格匹配——三者缺一,伪静态就只是看起来像而已。



















