VIP实战·碎片集

返回时间线

#Xunruicms #独立PHP程序 #被路由接管404

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 等配置保持不变 ...
}

操作步骤

  1. 将独立 PHP 文件夹放在 public 目录内(如 /public/zhengshu/)
  2. 在宝塔面板 → 网站 → 设置 → 配置文件 中添加 location ~ \.php$ 块
  3. 保存配置,重载 Nginx :nginx -t && nginx -s reload
  4. 访问测试

五、问题根因总结

问题 原因
文件夹找不到 文件夹建在了 public 外面,而运行目录是 public
PHP 文件不执行 Nginx 配置中缺少 location ~ \.php$ 块,未配置 PHP-FPM 转发
配置保存失败 误将 server 级别的指令写入了伪静态规则文件(rewrite 目录)

六、经验教训

  1. Xunruicms 运行目录:专业版/安全版的运行目录是 public,独立文件需放在 public 内
  2. 伪静态规则文件 vs 主配置文件:
    • 伪静态规则文件(rewrite 目录):只放 location / { ... } 内的规则
    • 主配置文件(nginx 目录):放 server 块、location ~ \.php$ 等全局配置
  3. PHP 处理块必不可少:即使伪静态规则中放行了 PHP 文件,如果没有 location ~ \.php$ 块, Nginx 不知道如何将 PHP 请求转发给 PHP-FPM 解析