PHP 8.1.25 在 IIS 10 上虚拟目录配置失败的主因是:虚拟目录被误设为应用程序、index.php 未加入并置顶默认文档列表、IIS_IUSRS 缺少对物理路径或 php-cgi.exe 的读取/执行权限。

直接说结论:PHP 8.1.25 在 IIS 10 上创建虚拟目录本身和 PHP 版本无关,关键在虚拟目录是否被误设为“应用程序”,以及 index.php 是否在默认文档列表中且排第一。
别把虚拟目录当成应用程序
这是最常踩的坑——你右键虚拟目录,发现“转换为应用程序”是灰色的,说明它已经被识别成应用程序了。一旦这样,IIS 就会绕过 StaticFileModule,走完整的请求管道,而你的 PHP 配置(比如 FastCgiModule 映射)可能只配在站点或应用程序级别,没继承下来,结果访问 /soft/index.php 直接 404 或 500。
- 检查方法:打开
%windir%\System32\inetsrv\config\applicationHost.config,搜索对应站点下的<virtualDirectory>标签;如果同时存在同 path 的<application>标签,就冲突了 - 修复方式:右键该虚拟目录 → “移除应用程序”,再重新添加为纯虚拟目录
- 物理路径必须有读取权限:确保
IIS_IUSRS对你指定的文件夹(如C:\www\soft)有“读取”权限,不需要“修改”
默认文档必须手动加 index.php 并置顶
IIS 10 默认文档列表里压根没有 index.php,哪怕你 PHP 跑得再稳,不加这一项,访问 /soft/ 就会返回 403.14(禁止目录浏览)或直接跳到父站点默认页。
- 操作路径:IIS 管理器 → 网站 → 双击“默认文档” → 右侧“添加” → 输入
index.php→ 点击“上移”直到它排第一位 - 注意:这个设置要加在**虚拟目录所在站点层级**,不是服务器全局;如果虚拟目录下还有子目录,且子目录也要支持
index.php,那该子目录也得单独配(或统一在站点级配好并继承) - 验证是否存在:
C:\www\soft\index.php这个文件必须真实存在,内容至少含<?php echo 'OK'; ?>,且不能是 UTF-8 BOM 编码(容易导致空白输出或 500)
FastCgiModule 映射必须覆盖虚拟目录路径
虚拟目录本身不继承处理程序映射,除非你明确在站点级配置了 *.php → FastCgiModule,并且没被子级配置覆盖或禁用。
立即学习“PHP免费学习笔记(深入)”;
- 检查位置:IIS 管理器 → 站点 → 双击“处理程序映射” → 查看是否有名称含
PHP、路径为*.php、模块为FastCgiModule的条目 - 可执行文件路径必须指向
php-cgi.exe(不是php.exe),例如:C:\php81\php-cgi.exe;PHP 8.1.25 必须是 NTS(非线程安全)版,否则 FastCGI 会崩溃 - 如果用了 APPCMD 脚本配置,确认没漏掉这行:
appcmd set config /section:system.webServer/handlers /+[name='PHP_via_FastCGI',path='*.php',...] - 权限补充:
IIS_IUSRS还需对php-cgi.exe所在目录有“读取+执行”权限,否则报 500.0 - FastCGI 进程意外退出
路径和字符限制比你想的更严格
Windows + IIS + PHP 组合对路径特别敏感,很多 404/500 其实和代码无关,纯粹是路径惹的祸。
- 物理路径避免中文、空格、长路径:比如
C:\my site\php-app\soft或C:\项目\soft很可能失败;推荐全英文、无空格、总长度 ≤240 字符,例如C:\www\soft - 别用
inetpub\wwwroot下的子目录直接当虚拟目录物理路径:IIS 有时会对该目录做特殊处理,建议统一放在其他盘符(如D:\web\soft) - PHP 配置里
doc_root不用动,IIS 不读这个;但extension_dir必须正确,否则mysqli、pdo_mysql等扩展加载失败,连带导致 500
真正卡住人的地方,往往不是 PHP 版本号写错,而是虚拟目录被悄悄转成应用程序、index.php 没进默认文档列表、或者 php-cgi.exe 权限没给够 —— 这三处查完,90% 的问题就定位到了。



















