Nginx PHP脚本执行404错误排查与解决方案
不少开发者和运维人员在部署PHP项目时会遇到这样的问题:通过浏览器访问PHP脚本时返回404状态码,但静态HTML文件可以正常访问。这类问题通常不是PHP本身的问题,而是Nginx和PHP的衔接配置出现了疏漏。下面我们从常见原因入手,逐步排查并给出对应的解决方案。
一、先确认基础环境是否正常
排查的第一步是确认Nginx和PHP-FPM服务都正常运行,且PHP-FPM的监听配置和Nginx的转发配置匹配。
首先查看Nginx服务状态,不同系统的命令略有区别:
# CentOS/RHEL系统 systemctl status nginx # Ubuntu/Debian系统 service nginx status
如果服务未运行,使用启动命令拉起:
# CentOS/RHEL系统 systemctl start nginx # Ubuntu/Debian系统 service nginx start
接着检查PHP-FPM服务状态,PHP版本不同,服务名可能带版本号,比如php-fpm74、php8.2-fpm等:
# 查看服务名 systemctl list-units | grep php-fpm # 查看服务状态 systemctl status php-fpm # 或对应版本的服务名
如果PHP-FPM未运行,同样启动服务:
systemctl start php-fpm
二、检查Nginx的PHP转发配置
404问题的核心多数出在Nginx没有正确把PHP请求转发给PHP-FPM处理,而是把PHP文件当成了静态文件去查找,找不到就返回404。我们需要检查Nginx站点配置里的PHP处理块。
常见的正确配置示例如下,假设PHP-FPM通过Unix socket监听:
server {
listen 80;
server_name example.ipipp.com; # 替换为你的域名或IP
root /var/www/html; # 项目根目录
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# PHP脚本转发配置
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock; # 替换为你的PHP-FPM监听地址
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}这里有几个容易出错的点,需要逐一核对:
- fastcgi_pass地址匹配:如果PHP-FPM监听的是TCP端口(比如127.0.0.1:9000),就需要把fastcgi_pass改成对应的TCP地址,不能混用socket和TCP方式。可以查看PHP-FPM的配置文件确认监听方式,通常在
/etc/php-fpm.d/www.conf或者/etc/php/8.2/fpm/pool.d/www.conf里,找到listen配置项:
; PHP-FPM监听配置示例,二选一 listen = /run/php-fpm/www.sock ; Unix socket方式 ; listen = 127.0.0.1:9000 ; TCP端口方式
- SCRIPT_FILENAME参数正确:这个参数必须指向PHP脚本的真实路径,很多错误都是因为这里写成了
$fastcgi_script_name漏了$document_root,导致PHP-FPM找不到文件返回404。 - location正则匹配正确:
location ~ \.php$是正则匹配以.php结尾的请求,注意不要写成location ~ \.php,否则可能匹配到不存在的路径。
修改完Nginx配置后,一定要重载配置让修改生效:
nginx -t # 先检查配置语法是否有误 systemctl reload nginx # 重载配置
三、检查文件权限与路径问题
如果转发配置没问题,还要确认PHP文件本身的存在性和权限是否正确。
首先确认访问的PHP文件路径在配置的root目录下真实存在,比如访问http://example.ipipp.com/test.php,就检查/var/www/html/test.php是否存在:
ls -l /var/www/html/test.php
如果文件不存在,自然返回404,需要上传或者创建对应的文件。如果文件存在,再检查Nginx和PHP-FPM的运行用户是否有读取权限。Nginx默认运行用户是nginx或者www-data,PHP-FPM的运行用户也在www.conf里的user和group配置项:
; www.conf用户配置示例 user = nginx group = nginx
确保项目目录和PHP文件的权限至少让运行用户有读取权限,简单的权限调整命令如下:
# 调整项目目录权限,递归给运行用户
chown -R nginx:nginx /var/www/html
# 给目录755、文件644权限
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;四、检查Nginx的try_files配置
很多站点的location /块里会配置try_files规则,如果规则不当,也会导致PHP请求被拦截返回404。比如错误的配置可能写成:
location / {
try_files $uri $uri/ /index.php?$query_string;
}如果这里的逻辑有问题,或者没有把PHP请求排除在try_files的静态文件查找之外,就可能出问题。正确的做法是在PHP的location块里优先处理请求,避免被其他try_files规则拦截。
另外如果站点用了伪静态规则,也要确认规则没有把合法的PHP请求重写到不存在的路径上,可以暂时注释掉伪静态规则测试是否正常访问,再逐步排查规则问题。
五、查看日志定位具体原因
如果以上步骤都没问题,就可以通过查看日志找到更准确的错误原因。
首先看Nginx的错误日志和访问日志,默认路径通常在/var/log/nginx/error.log和/var/log/nginx/access.log:
# 查看Nginx错误日志,实时刷新 tail -f /var/log/nginx/error.log # 访问页面后查看访问日志的请求状态 tail -f /var/log/nginx/access.log
如果Nginx日志里显示请求返回404,但是文件路径正确,再看PHP-FPM的错误日志,路径通常在/var/log/php-fpm/error.log或者/var/log/php8.2-fpm.log:
tail -f /var/log/php-fpm/error.log
如果PHP-FPM日志里出现“Primary script unknown”的错误,基本就是SCRIPT_FILENAME配置错误或者文件权限问题,对照之前的步骤调整即可。
六、快速验证方法
排查过程中可以创建一个简单的PHP测试文件,快速验证环境是否正常:
<?php phpinfo(); // 输出PHP环境信息,验证PHP是否正常执行 ?>
把这段代码保存为info.php放到项目根目录,访问http://example.ipipp.com/info.php,如果能看到PHP信息页面,说明配置正常;如果还是404,就按照前面的步骤逐一核对。