Xunruicms 增加独立 PHP 程序被路由接管 404 问题排查与解决全记录
一、问题描述
在 Xunruicms 网站根目录下新建文件夹,放入独立的 PHP 程序文件,通过完整 URL 访问时,请求被 Xunruicms 路由接管,显示 404 错误页面。具体表现为:新建的 zhengshu 目录下的 index.php 无法正常访问。
二、环境信息
| 项目 | 配置 |
|---|---|
| 网站域名 | www.ccc.cn |
| CMS 系统 | Xunruicms |
| 网站根目录 | /www/wwwroot/www.ccc.cn/public |
| PHP 版本 | 8.0 |
| PHP 套接字 | unix:/tmp/php-cgi-80.sock |
| Web 服务器 | Nginx 1.24.0 |
| 服务器面板 | 宝塔面板 |
三、排查过程
第 1 步:分析伪静态规则
原始伪静态规则如下:
location / {
if (-f $request_filename) {
break;
}
if ($request_filename ~* "\.(js|ico|gif|jpe?g|bmp|png|css)$") {
break;
}
if (!-e $request_filename) {
rewrite . /index.php last;
}
}
该规则逻辑:
- 文件存在 → 放行
- 静态资源( js/css/图片等)→ 放行
- 文件/目录不存在 → 重写到
index.php由 CMS 处理
初步判断:规则中只放行了静态资源扩展名,没有放行 PHP 文件,导致 PHP 请求被重写。
第 2 步:尝试方案一——在规则中添加 PHP 扩展名
将 php 加入放行列表:
if ($request_filename ~* "\.(js|ico|gif|jpe?g|bmp|png|css|php)$") {
break;
}
结果:问题依旧。
第 3 步:尝试方案二——单独排除目录
添加 location /zhengshu/ 块:
location /zhengshu/ {
try_files $uri $uri/ =404;
}
结果:目录可以访问,能看到文件列表,但 PHP 文件仍不执行,返回空白内容。
第 4 步:发现运行目录问题
Xunruicms 专业版/安全版的网站运行目录是 public 子目录。确认网站根目录为 /www/wwwroot/www.ccc.cn/public,而 zhengshu 文件夹建在了 public 外面,导致 Nginx 找不到。
解决:将 zhengshu 文件夹移到 public 目录内。
结果:目录可正常访问,但 PHP 文件仍无法解析执行。
第 5 步:发现缺少 PHP 处理块
根本原因: Nginx 配置中缺少 location ~ \.php$ 块,没有告诉 Nginx 如何将 PHP 文件转发给 PHP-FPM 进程解析。
第 6 步:配置 PHP 处理块
在宝塔面板的网站主配置文件(非伪静态规则文件)中,添加 PHP 处理块:
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi-80.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
放置位置:在 server 块中,include extension 之后、include rewrite 之前。
注意:该配置必须放在主配置文件(/www/server/panel/vhost/nginx/www.ccc.cn.conf)的 server 块中,不能放在伪静态规则文件(/www/server/panel/vhost/rewrite/www.ccc.cn.conf)中,否则会报错 "server" directive is not allowed here。
四、最终解决方案
完整 Nginx 配置(关键部分)
server
{
listen 80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
listen [::]:80;
server_name www.ccc.cn;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/www.ccc.cn/public;
include /www/server/panel/vhost/nginx/extension/www.ccc.cn/*.conf;
# ===== 添加 PHP 处理块 =====
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi-80.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# ============================
# ... 其他 SSL 、 rewrite 等配置保持不变 ...
}
操作步骤
- 将独立 PHP 文件夹放在
public目录内(如/public/zhengshu/) - 在宝塔面板 → 网站 → 设置 → 配置文件 中添加
location ~ \.php$块 - 保存配置,重载 Nginx :
nginx -t && nginx -s reload - 访问测试
五、问题根因总结
| 问题 | 原因 |
|---|---|
| 文件夹找不到 | 文件夹建在了 public 外面,而运行目录是 public |
| PHP 文件不执行 | Nginx 配置中缺少 location ~ \.php$ 块,未配置 PHP-FPM 转发 |
| 配置保存失败 | 误将 server 级别的指令写入了伪静态规则文件(rewrite 目录) |
六、经验教训
- Xunruicms 运行目录:专业版/安全版的运行目录是
public,独立文件需放在public内 - 伪静态规则文件 vs 主配置文件:
- 伪静态规则文件(
rewrite目录):只放location / { ... }内的规则 - 主配置文件(
nginx目录):放server块、location ~ \.php$等全局配置
- 伪静态规则文件(
- PHP 处理块必不可少:即使伪静态规则中放行了 PHP 文件,如果没有
location ~ \.php$块, Nginx 不知道如何将 PHP 请求转发给 PHP-FPM 解析