文章目录▼CloseOpen
- 第一步:选对版本,别再瞎下软件(踩过版本不兼容的坑才懂)
- 第二步:改配置文件,重点是这3个地方(新手最容易错)
- 第三步:启动服务,测试是否能解析PHP(最后一步别忘验证)
- Nginx启动时提示“端口被占用”怎么办?
- 访问.php文件直接下载而不解析,怎么解决?
- 关闭PHP的命令行窗口后,Nginx就无法解析PHP了,怎么办?
- phpinfo()里看不到mysqli或pdo_mysql扩展,怎么解决?
- 先改PHP的php.ini,开CGI和扩展
- extension_dir:这是PHP扩展的路径,比如你的PHP在D盘“php-8.2.12”,就写成“extension_dir = “D:php-8.2.12ext””。我表弟之前把路径写成“D:php-8.2.12ext”(多了个斜杠),结果启动PHP时,扩展全加载失败,访问phpinfo()根本看不到mysqli扩展——别小看这个斜杠,Nginx和PHP解析路径时,多余的斜杠会导致路径无效。
- cgi.fix_pathinfo:把前面的分号去掉,改成“cgi.fix_pathinfo=1”。这个参数是让PHP正确解析请求的路径,比如你访问“http://localhost/index.php?id=1”,PHP需要知道脚本是index.php,而不是index.php?id=1——要是没开这个参数,Nginx转发过来的请求,PHP会找不到脚本。
- 开启常用扩展:比如mysqli(连接MySQL)、pdo_mysql(PDO连接MySQL),把这些扩展前面的分号去掉。比如“extension=mysqli”“extension=pdo_mysql”——我之前帮朋友配置时,忘了开mysqli扩展,结果他写的登录页面一直报“Call to undefined function mysqli_connect()”,查了半小时才发现是扩展没开。
- Nginx配置文件:关键是fastcgi的参数要填对
第一步:选对版本,别再瞎下软件(踩过版本不兼容的坑才懂)
先吐槽一句:新手最容易犯的错就是“随便下最新版”,但版本不兼容真的会搞死人。比如我之前帮朋友下了Nginx 1.25.0(开发版),结果和PHP 8.2搭配时,fastcgi模块老报错,后来换了稳定版1.24.0就好了——Nginx官网明确说,稳定版适合生产环境,开发版有新功能但可能有bug,新手直接选稳定版准没错(官网地址:https://nginx.org/zh-cn/)。
再来说PHP:Windows下配置Nginx+PHP,一定要选线程安全版(TS),别选非线程安全版(NTS)。为什么?PHP官网文档里写得很清楚:Windows下使用CGI模式(也就是我们要配的fastcgi),必须用线程安全版——我之前帮朋友下了NTS版,结果配置完fastcgi一直报“PHP Fatal error: Invalid opcode 153/1/8.”,查了3小时文档才找到原因,就是版本选错了。PHP的下载地址是https://www.php.net/,进下载页选“Windows downloads”,然后找“Thread Safe”的.zip包,比如“PHP 8.2.12 Thread Safe (x64)”。
下好软件后,解压的位置也有讲究:别放带空格的目录,比如“Program Files”这种。我表弟之前把PHP放到“D:Program Filesphp”,结果Nginx解析路径时,把空格当成分隔符,直接把路径读成“D:Program”,启动时 error.log 里全是“invalid path”。正确的做法是放到根目录,比如把Nginx解压到D盘,命名为“nginx-1.24.0”,PHP解压到D盘“php-8.2.12”,路径里没有空格,Nginx就能正确识别。
第二步:改配置文件,重点是这3个地方(新手最容易错)
软件放对位置后,接下来改配置文件——这是新手最容易翻车的环节,我整理了3个必改的地方,每一步都附带着“为什么要改”,不然你记不住。
PHP解压后,文件夹里有两个ini文件:php.ini-development(开发环境用)和php.ini-production(生产环境用)。新手直接复制php.ini-development,改名为php.ini——开发环境的配置更宽松,方便调试。
接下来改3个关键参数:
改完后保存php.ini,别着急关,等下启动PHP时要用到。
Nginx的配置文件在“nginx-1.24.0confnginx.conf”,用记事本打开就行。重点改server块里的内容,我把正确的配置贴出来,你对照着改:
server {
listen 80;
server_name localhost;
root D:/www; # 网站根目录,和PHP的index.php位置一致
index index.html index.htm index.php; # 加index.php
# 处理PHP文件的转发
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000; # 对应PHP的CGI端口
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 关键!
include fastcgi_params;
}
}
这里有2个新手必错的点:
改完后,一定要测试配置文件!打开命令提示符,进入Nginx目录,输入“nginx -t”——如果显示“nginx: configuration file D:nginx-1.24.0/conf/nginx.conf test is successful”,说明配置没错;要是报错,比如“invalid port in upstream”,就是fastcgi_pass的端口写错了,赶紧改。我之前把端口写成“127.0.0.1:900”(少个0),测试时直接提示错误,省得启动后再找问题。
很多新手改完配置文件,直接双击nginx.exe启动,结果要么启动不了,要么访问报错——其实Nginx提供了配置文件测试命令,就是“nginx -t”,一定要先测!比如我之前把root写成“D:www”(多了个斜杠),测试时直接提示“invalid path”,要是没测就启动,error.log里全是错,还得回头找。
第三步:启动服务,测试是否能解析PHP(最后一步别忘验证)
配置文件改对后,接下来启动服务——这一步要按顺序来,先启动PHP的CGI进程,再启动Nginx。
打开命令提示符(别用PowerShell,用cmd就行),进入PHP目录,输入:
php-cgi.exe -b 127.0.0.1:9000 -c D:php-8.2.12php.ini
解释一下参数:
启动后,命令提示符会保持打开状态——别关!一关PHP进程就停了,Nginx就找不到PHP了。
进入Nginx目录,双击“nginx.exe”,或者命令行输入“start nginx”——启动后,任务管理器里会有两个nginx进程,说明启动成功。
在Nginx的root目录(比如D:/www)里,新建一个“index.php”文件,内容就写:
<?php phpinfo();
?>
然后打开浏览器,访问“http://localhost”——如果能看到PHP的信息页面,比如PHP版本、扩展列表、配置参数,就说明配置成功了!
要是碰到问题,比如:
碰到这些问题别慌,去看Nginx的error.log(在nginx/logs/error.log),里面会写清楚错误原因——比如我之前把root写成“D:www1”(多了个1),error.log里直接提示“file not found”,一眼就看出问题。
最后我整理了一个新手常犯错误表,碰到问题直接查:
错误现象 | 常见原因 | 解决办法 |
---|---|---|
访问.php文件直接下载 | Nginx没配置PHP转发 | 检查location ~ .php$的配置,确保fastcgi参数正确 |
502 Bad Gateway | PHP CGI进程没启动或端口不对 | 重新启动PHP CGI,检查fastcgi_pass的端口是否一致 |
路径错误 | 路径带空格或斜杠错误 | 把软件放到根目录,路径别带空格,斜杠用正斜杠或双反斜杠 |
扩展没加载 | extension_dir路径错或没开扩展 | 检查extension_dir的路径,去掉扩展前面的分号 |
按这些步骤做完,应该就能正常解析PHP了。要是还有问题,欢迎在评论区告诉我——比如你碰到“Nginx启动不了”,可以把error.log里的内容贴出来,我帮你看看。我之前帮朋友解决过一个问题:他把nginx.conf里的“listen 80”写成“listen 8080”,结果访问localhost时,浏览器一直转圈,后来改回80就好了。
对了,要是你想让PHP和Nginx开机自启,可以做个批处理文件,不过新手暂时不用搞这个——先把基础配置搞定,再折腾自启的事。
如果你按方法试了,欢迎回来告诉我效果!比如“我用这个方法半小时就搞定了”或者“碰到了XX问题”,我会一一回复的。
我之前帮邻居家刚学PHP的小孩配置环境时,他就踩过这个坑——把写好的index.php放到D盘www目录里,兴高采烈打开浏览器输localhost/index.php,结果浏览器直接弹“是否保存index.php”的对话框,他急得直拍桌子:“我明明按教程做的,怎么变成下载了?”其实哪是教程的问题?本质是Nginx没“通知”PHP来处理这个.php文件,直接把它当普通的文本文件发给浏览器了,浏览器不认识PHP代码,只能让你下载。
先别急着卸载软件,咱们先查Nginx的配置——打开Nginx目录下conf文件夹里的nginx.conf,找到处理PHP的“location ~ .php$”块(就是专门管.php文件的规则)。第一个要盯紧的是“fastcgi_pass”这个参数,它得和你启动PHP时用的端口完全一致。比如你启动PHP时输的是“php-cgi.exe -b 127.0.0.1:9000”,那Nginx里这儿必须写“127.0.0.1:9000”;要是你手滑写成9001或者把端口漏了,Nginx根本找不到PHP进程,自然没法让PHP解析文件。我之前帮同事解决过一次,他就是把这儿写成80了(和Nginx自己的监听端口冲突),改回9000重启Nginx,立马就好了。
还有个“要命”的参数叫“fastcgi_param SCRIPT_FILENAME”,这行必须写成“$document_root$fastcgi_script_name”——别漏了前面的$document_root!我朋友之前配置时,嫌麻烦把$document_root删了,直接写$fastcgi_script_name,结果PHP以为脚本在自己的安装目录(比如D:php-8.2.12)里,可实际上脚本在Nginx的www目录(D:www),PHP找不着文件,只能返回错误,Nginx又把错误当普通文件发出去,可不就变成下载了嘛?
改完这俩参数,先别着急重启Nginx,用“nginx -t”命令测测配置对不对(要是提示“test is successful”才对)。没问题了再重启Nginx——还有个关键点:得确认PHP的CGI进程没关掉!要是你刚才把启动PHP的命令行窗口关了,PHP进程早没了,Nginx喊破喉咙也找不到它。赶紧重新打开命令行,进入PHP目录,输入启动命令(记得加-c参数指定php.ini路径),等进程跑起来,再刷新浏览器试试——保准能看到phpinfo的信息页面,再也不会弹下载框了。
Nginx启动时提示“端口被占用”怎么办?
首先用命令提示符输入netstat -ano | findstr ":80"
,查看占用80端口的进程PID(最后一列数字),然后打开任务管理器,找到对应PID的进程(比如IIS的inetinfo.exe或Apache的httpd.exe)并结束;如果不想关闭其他程序,可以修改Nginx配置文件里的listen 80;
为其他未占用端口(如8080),保存后重新启动Nginx,访问时用localhost:8080
即可。
访问.php文件直接下载而不解析,怎么解决?
这种情况通常是Nginx没正确将PHP请求转发给PHP处理。首先检查Nginx配置文件中的location ~ .php$
块:确保fastcgi_pass 127.0.0.1:9000;
(端口与PHP启动的端口一致),且fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
没有写错;然后重启Nginx,同时确认PHP CGI进程处于运行状态。
关闭PHP的命令行窗口后,Nginx就无法解析PHP了,怎么办?
PHP CGI进程需要保持运行才能处理Nginx的请求,关闭命令行窗口会终止进程。新手可以暂时不关闭窗口(最小化即可);如果想让进程后台运行,可以下载RunHiddenConsole
工具(一个轻量级的后台运行工具),将PHP启动命令写成批处理文件(如RunHiddenConsole php-cgi.exe -b 127.0.0.1:9000 -c D:php-8.2.12php.ini
),双击运行批处理即可让PHP在后台保持运行。
phpinfo()里看不到mysqli或pdo_mysql扩展,怎么解决?
首先检查php.ini中的extension_dir
路径是否正确(如extension_dir = "D:php-8.2.12ext"
),确保路径没有空格或错误;然后检查扩展前的分号是否去掉(如extension=mysqli
和extension=pdo_mysql
);最后确认启动PHP时是否指定了正确的php.ini路径(启动命令中的-c
参数),比如php-cgi.exe -b 127.0.0.1:9000 -c D:php-8.2.12php.ini
,修改后重启PHP和Nginx即可。