nginx中windows下配虚拟目录需用location + alias(结尾带/)+ 显式root + $document_root拼接script_filename,且php.ini必须设cgi.fix_pathinfo=1;否则易404或502。

nginx.conf 里 location 块怎么写虚拟目录
Windows 下用 Nginx 给 PHP 配虚拟目录(比如 /admin 或 /api),本质是让 Nginx 把特定 URL 路径映射到对应物理目录,并正确转发 PHP 请求。不能只靠 alias,必须配合 root + SCRIPT_FILENAME 手动拼接,否则 502 或 File not found 是常态。
常见错误现象:
访问 http://localhost/admin/index.php 返回 404;
或返回 502,Nginx error.log 显示 FastCGI sent in stderr: "Primary script unknown"。
实操建议:
• 虚拟目录路径必须以 / 开头,且 location 块中不要带 trailing slash(如写成 location /admin/ 容易导致 $fastcgi_script_name 多出斜杠)
• 必须显式设置 root 指向主站点根目录,再用 alias 指向虚拟目录的物理路径
• SCRIPT_FILENAME 必须用 $document_root + $fastcgi_script_name 拼接,不能依赖 alias 自动替换
正确示例(虚拟目录 /admin 指向 E:/WWW/admin):
location /admin {
alias E:/WWW/admin/;
index index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
php.ini 里 cgi.fix_pathinfo=1 还是 0
这个值直接决定虚拟目录下 PHP 脚本能被找到还是报 File not found。Windows + Nginx 场景下,必须设为 cgi.fix_pathinfo=1,否则 $fastcgi_script_name 解析会丢掉路径前缀。
原因:Nginx 传给 PHP-CGI 的 SCRIPT_FILENAME 是完整绝对路径,而 PHP 在 cgi.fix_pathinfo=0 时会跳过路径解析逻辑,仅检查脚本名是否在当前目录下——这在虚拟目录场景下必然失败。
实操建议:
• 打开 php.ini,搜索 cgi.fix_pathinfo
• 确保该行未被注释,且值为 1:cgi.fix_pathinfo=1
• 改完后必须重启 php-cgi.exe 进程,否则不生效
• 注意:cgi.force_redirect=0 也必须设为 0,否则所有请求会被拦截返回 404
为什么 alias 后面的路径结尾必须加 /
alias 在 Nginx 中不是简单替换字符串,而是“路径重映射”。结尾缺 / 会导致子请求路径计算错位,尤其影响 .php 文件定位。
PHP 8.5.12 RC 1 候选版修复 BZ2、DOM、PDO、Opcache/JIT 和扩展内存安全问题,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
举例:
若写 alias E:/WWW/admin(无尾部 /),访问 /admin/test.php 时,Nginx 会尝试把 test.php 拼到 E:/WWW/admintest.php(中间没斜杠),直接 404。
加上 / 后,E:/WWW/admin/ + test.php → E:/WWW/admin/test.php,才对。
实操建议:
• 所有 alias 值末尾必须带 /
• 路径中统一用正斜杠 /,避免混用 \(Windows 下 \ 在配置里可能被误解析为转义符)
• 若物理路径含空格(如 E:/My Project/admin),整个路径必须用双引号包裹:alias "E:/My Project/admin/";
PHP-CGI 进程要怎么启动才支持多虚拟目录
PHP-CGI 本身不感知虚拟目录,它只按 Nginx 传来的 SCRIPT_FILENAME 去执行文件。所以只要 Nginx 配置正确、php.ini 关键项设对,一个 php-cgi.exe -b 127.0.0.1:9000 进程就能服务全部虚拟目录。
但容易踩的坑:
• 多个虚拟目录指向不同磁盘(如 C:/ 和 E:/),需确保 php.ini 中 open_basedir 没限制路径(默认为空,安全起见可显式设为 none)
• session.save_path 和 upload_tmp_dir 必须是真实存在的绝对路径,且 PHP 进程有写权限(推荐用 C:/tool/PHP/session_temp 这类无空格路径)
• 不要用 php.exe 启动,必须用 php-cgi.exe(NTS 版本才有)
推荐启动命令(加 RunHiddenConsole.exe 防闪退):
RunHiddenConsole.exe php-cgi.exe -b 127.0.0.1:9000
验证方式:改完配置后,分别访问 http://localhost/admin/info.php 和 http://localhost/api/test.php,两个都能输出 phpinfo() 即说明通了。
最常被忽略的一点:Nginx 的 root 指令在虚拟目录 location 块外定义,但它仍参与 $document_root 变量计算——哪怕你用了 alias,$document_root 依然取自外层 server 块的 root。所以 SCRIPT_FILENAME 拼接时,必须确认 $document_root 是否真指向你想让 PHP 加载的目录,否则路径一错全盘皆输。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










