在 Windows Server 上配置 Nginx 和 PHP 的 Web 服务器时,访问 PHP 文件(如 http://localhost/info.php
)时可能会遇到 "No input file specified" 错误。这个错误表明 Nginx 成功连接到 PHP FastCGI 进程,但 PHP-CGI 无法找到请求的 PHP 文件。本文基于一个实际案例(PHP 8.4.10、Nginx 和 nginxWebUI,网站目录为 D:\program\nginx\html
),提供详细的诊断和解决步骤。
背景
配置环境如下:
- PHP 8.4.10(非线程安全版,安装在
D:\program\php\php-8.4.10-nts-Win32-vs17-x64
)。 - PHP-CGI 通过 NSSM 配置为服务,监听在
127.0.0.1:9000
。 - Nginx 安装在
C:\nginx
,网站根目录为D:\program\nginx\html
。 - 使用 nginxWebUI 管理 Nginx 配置。
- 目录权限已通过
icacls
设置为IUSR:(RX)
和Everyone:(RX)
。 - 初始 Nginx 配置问题:
root html;
和fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
导致 PHP-CGI 查找错误路径(例如/scripts/info.php
而非D:\program\nginx\html\info.php
)。
解决步骤
1. 验证 PHP-CGI 服务
确保 PHP-CGI 服务运行正常并监听正确端口。
-
检查服务状态:
Get-Service php-cgi
- 预期输出:
Status Name DisplayName ------ ---- ----------- Running php-cgi php-cgi
- 如果服务停止,重新启动:
& "D:\program\nssm\nssm.exe" start php-cgi
- 预期输出:
-
验证端口监听:
netstat -an | Select-String 9000
- 预期输出:
TCP 127.0.0.1:9000 0.0.0.0:0 LISTENING
- 如果端口未监听,检查冲突:
netstat -aon | Select-String 9000 Get-Process -Id <PID>
- 终止非 PHP-CGI 进程:
Stop-Process -Id <PID> -Force
- 终止非 PHP-CGI 进程:
- 预期输出:
-
确认单一 PHP-CGI 进程:
Get-Process | Where-Object { $_.Path -like "*php-cgi.exe*" }
- 应显示一个进程,路径为
D:\program\php\php-8.4.10-nts-Win32-vs17-x64\php-cgi.exe
。 - 如果有多个进程,停止它们:
Stop-Process -Name php-cgi -Force
- 如需重新安装 NSSM 服务:
& "D:\program\nssm\nssm.exe" remove php-cgi confirm & "D:\program\nssm\nssm.exe" install php-cgi "D:\program\php\php-8.4.10-nts-Win32-vs17-x64\php-cgi.exe" -b 127.0.0.1:9000 & "D:\program\nssm\nssm.exe" start php-cgi
- 应显示一个进程,路径为
2. 验证网站目录和权限
网站目录(D:\program\nginx\html
)必须存在且具有适当权限。
-
检查目录:
Test-Path "D:\program\nginx\html"
- 如果返回
False
,创建目录:New-Item -Path "D:\program\nginx\html" -ItemType Directory
- 如果返回
-
设置权限:
icacls "D:\program\nginx\html" /grant "IUSR:(RX)" icacls "D:\program\nginx\html" /grant "Everyone:(RX)"
-
创建测试文件:
在D:\program\nginx\html
创建info.php
:Set-Content -Path "D:\program\nginx\html\info.php" -Value '<?php phpinfo(); ?>'
- 验证文件:
Test-Path "D:\program\nginx\html\info.php" Get-Content "D:\program\nginx\html\info.php"
- 设置文件权限:
icacls "D:\program\nginx\html\info.php" /grant "IUSR:(RX)"
- 验证文件:
3. 修复 Nginx 配置
“No input file specified” 错误由错误的 root
和 fastcgi_param
设置引起。更新 C:\nginx\conf\nginx.conf
:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# 阻止直接 IP 访问
if ($host ~* "^[0-9.]+$|^[0-9a-f:]+$") {
return 444;
}
root D:/program/nginx/html;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root D:/program/nginx/html;
}
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;
}
}
}
-
关键更改:
- 将
root D:/program/nginx/html;
置于server
块顶部,避免冗余。 - 使用
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
动态生成文件路径(如D:/program/nginx/html/info.php
)。 - 添加
try_files
确保 PHP 路由正确。 - 修复
error_page
的root
为D:/program/nginx/html
。
- 将
-
验证
fastcgi_params
文件:
确保C:\nginx\conf\fastcgi_params
存在:Test-Path "C:\nginx\conf\fastcgi_params"
- 如果返回
False
,创建文件:Set-Content -Path "C:\nginx\conf\fastcgi_params" -Value @" fastcgi_param QUERY_STRING \$query_string; fastcgi_param REQUEST_METHOD \$request_method; fastcgi_param CONTENT_TYPE \$content_type; fastcgi_param CONTENT_LENGTH \$content_length; fastcgi_param REQUEST_URI \$request_uri; fastcgi_param DOCUMENT_URI \$document_uri; fastcgi_param SERVER_PROTOCOL \$server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param REMOTE_ADDR \$remote_addr; fastcgi_param REMOTE_PORT \$remote_port; fastcgi_param SERVER_ADDR \$server_addr; fastcgi_param SERVER_PORT \$server_port; fastcgi_param SERVER_NAME \$server_name; "@
- 如果返回
-
验证配置:
& "C:\nginx\nginx.exe" -t
- 预期输出:
nginx: the configuration file C:\nginx\conf\nginx.conf syntax is ok nginx: configuration file C:\nginx\conf\nginx.conf test is successful
- 预期输出:
-
重启 Nginx:
& "C:\nginx\nginx.exe" -s reload
4. 更新 nginxWebUI(如果适用)
如果使用 nginxWebUI:
- 访问
http://<server_ip>:8080
。 - 在 反向代理 或 静态文件 模块,更新
server
块为上述配置。 - 保存并通过 nginxWebUI 重启 Nginx。
5. 测试 PHP
- 浏览器访问
http://localhost/info.php
(因return 444
限制,勿用http://127.0.0.1/info.php
)。 - 如果显示 PHP 信息页面,问题解决。
- 如果仍有错误:
- No input file specified:
- 确认
D:\program\nginx\html\info.php
存在。 - 检查 Nginx 错误日志:
Get-Content "C:\nginx\logs\error.log" -Tail 10
- 直接测试 PHP:
& "D:\program\php\php-8.4.10-nts-Win32-vs17-x64\php.exe" "D:\program\nginx\html\info.php"
- 确认
- 403 Forbidden:重新检查权限:
icacls "D:\program\nginx\html"
- 502 Bad Gateway:验证 PHP-CGI 服务和端口。
- No input file specified:
6. 关于 Linux 的 chown
命令
用户询问了 Linux 命令 chown -R www:www ./*
,用于设置文件所有者和组。在 Windows 中,通过 icacls
设置权限(IUSR:(RX)
和 Everyone:(RX)
)已足够。如果在 Windows Subsystem for Linux (WSL) 或 Linux 服务器运行 Nginx:
- 检查 Nginx 用户:
grep user /etc/nginx/nginx.conf
- 设置权限:
sudo chown -R www-data:www-data /path/to/nginx/html
结论
通过以下步骤修复了 “No input file specified” 错误:
- 将
root
设置为D:/program/nginx/html
。 - 使用
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
提供正确文件路径。 - 确保 PHP-CGI 服务运行,网站目录权限正确。
按照这些步骤,您可以在 Windows Server 上成功配置 Nginx 和 PHP,实现动态 PHP 内容交付。始终验证配置和日志以捕获潜在问题。