欢迎光临
我们一直在努力

一边装一边报错:CentOS 7 + LNMP 跑 ECShop 的常见故障与解法

在 CentOS 7 上用 Nginx + PHP-FPM + MariaDB 搭 ECShop,新手几乎都会卡在 403、Primary script unknown、Session 写不进、目录不可写这几类报错。本文按「配置 → 版本 → 数据库 → 权限 → 时区 → 源」的顺序,把 11 类高频问题一次排清,每类都给出现场报错、根因和可直接照抄的修复命令;文中命令名均标注英文全称(如 chown = change owner),完整清单见文末《附:命令英文全称速查表》。

ECShop 在 LNMP 架构下各组件与高频报错分布概念图

本文概要:

项目内容
文章主题 ECShop 在 CentOS 7 + Nginx + PHP-FPM + MariaDB 上的部署报错排查,按问题类型给出根因与修复命令
所属类别 Linux 系统运维 → Web 服务部署 → LNMP 排错
知识关键字 nginx · php-fpm · SCRIPT_FILENAME · root · chown · chmod · session · date.timezone · mariadb · Remi · CentOS-Vault

一、环境说明与前置条件

实验环境:CentOS 7.9、Nginx、PHP-FPM、MariaDB、ECShop 4.x。

ECShop 是老程序,PHP 版本兼容是第一条红线:5.6 / 7.2 / 7.3 可正常跑;7.4 起报弃用警告;8.x 直接致命错误。动手前先确认 PHP 版本:

php -v # 看 PHP 版本,决定要不要降级
nginx -v # 看 Nginx 版本
mysql –version # 看 MariaDB 版本

CentOS 7 已停止维护,yum 官方源失效,装包前必须先把源切到可用镜像(见第八章),否则后面所有 yum install 都会失败。

二、Nginx 与 PHP-FPM:3 个配置坑

部署 ECShop 最高频的翻车区:表象是 403 / 空白页 / Primary script unknown,根因几乎都归结为「root 作用域」和「index 指令」。

2.1 Primary script unknown(PHP-FPM 找不到脚本)

报错日志

FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream,
client: 10.1.8.12, server: www.zhb.cloud, request: "GET /test.php HTTP/2.0",
upstream: "fastcgi://127.0.0.1:9000", host: "www.zhb.cloud"

根因

Nginx 传给 PHP-FPM 的 SCRIPT_FILENAME 路径不对,PHP-FPM 在自己的文件系统里找不到脚本。三类诱因:

  • root 只写在 location / 块里、没写在 server 顶层 → $document_root 为空,SCRIPT_FILENAME 只拼出 /test.php。
  • root 写进了某个 location 块内部(块级默认 root)。root 有作用域,只对当前块生效;location / 里的 root 不会「继承」给 location ~ \\.php$,PHP 请求吃不到。
  • 全局 root 已存在,但某 location 块又写了(默认)root,把全局 root 覆盖掉。常见于从默认配置复制时残留的 root /usr/share/nginx/html;——若那条路径没有 PHP 文件,$document_root 取到错误目录,照样报 Primary script unknown。
  • Primary script unknown 的 root 作用域对比(错误配置与正解配置)

    ⚠️ 注意:root 一律写 server 顶层,或给每个 location 都显式写 root;别把 root 塞进 location / 当「默认 root」,也别残留 root /usr/share/nginx/html; 偷偷覆盖全局。改完用 nginx -T 2>/dev/null | grep -n root 全局扫一遍确认。

    排查:开 Nginx debug 日志,看实际传出的 SCRIPT_FILENAME:

    location ~ \\.php$ {
    error_log /var/log/nginx/php-debug.log notice;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
    }

    grep -i script_filename /var/log/nginx/php-debug.log

    若输出只有 /test.php(无目录前缀),就是 root 作用域问题。

    解决

    把 root 移到 server 块顶层,并确保 fastcgi_param SCRIPT_FILENAME 写在 include fastcgi_params; 之后(后写覆盖前写):

    server {
    listen 80;
    server_name www.zhb.cloud;
    root /website/ecshop; # ← 放这里,全 server 生效

    index index.php index.html index.htm;

    location / {
    try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \\.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
    }
    }

    nginx -t && nginx -s reload

    2.2 directory index of “…/install/” is forbidden(403)

    根因

    请求的是目录 /install/,但 Nginx 的 index 指令里没有 index.php,找不到默认索引文件;又因为 autoindex 默认关闭,于是返回 403。index.php 文件本身存在且权限正常。

    解决

    在 server 块里加 index 指令,把 index.php 放最前:

    index index.php index.html index.htm;

    改完 nginx -s reload。/test.php 是具体文件,命中 location ~ \\.php$,不涉及 index;/install/ 是目录,必须靠 index 决定首页(详见下方 403 成因图)。

    2.3 文件权限链排查

    不仅文件本身要有读权限,从根目录到该文件的每一级目录都必须对 PHP-FPM 用户有 x(进入)权限。任何一级缺 x,即使文件是 777,PHP-FPM 也进不去。

    namei -l /website/httpsweb/test.php

    dr-xr-xr-x root root /
    drwxr-xr-x root nginx website
    drwxr-xr-x root nginx httpsweb
    -rw-r–r– root nginx test.php

    namei -l 逐层列出每级目录的权限与属主,哪一列没有 x 一眼可见。

    Nginx 403 的两类成因:目录索引缺失与权限链缺 x

    三、PHP 版本与扩展兼容

    3.1 花括号偏移访问弃用(curly braces deprecated)

    报错内容

    Deprecated: Array and string offset access syntax with curly braces is deprecated
    in /website/ecshop/includes/lib_base.php on line 1071

    根因

    PHP 7.4 弃用了用花括号 {} 访问数组/字符串偏移量的写法(如 $str{0}),PHP 8.0 彻底移除。ECShop 老代码大量使用此语法。

    PHP 版本是否报错
    5.3 / 5.4 / 5.6 不报
    7.0 ~ 7.3 不报
    7.4 开始报 Deprecated
    8.x 致命错误

    PHP 版本与 ECShop 兼容性颜色条:5.6 与 7.0-7.3 不报错,7.4 报弃用警告,8.x 致命错误

    ⚠️ 注意:ECShop 建议锁 PHP 5.6 或 7.2/7.3,避开 7.4+ 的弃用警告与 8.x 的致命错误。PHP 5.6/7.3 已停止维护,存在安全风险,生产环境先在测试机验证。

    解决:降级 PHP(见 3.2);或把 $str{0} 改成 $str[0],批量查找:

    grep -rn '{[0-9]}' /website/ecshop/includes/

    3.2 PHP 降级命令(CentOS 7 + Remi)

    以从 7.4 降到 5.6 为例:

    # 1. 备份配置
    cp /etc/php.ini /etc/php.ini.bak
    cp -r /etc/php-fpm.d /etc/php-fpm.d.bak

    # 2. 卸载当前 PHP
    yum remove php-* -y
    yum autoremove -y

    # 3. 切换仓库
    yum-config-manager –disable remi-php74
    yum-config-manager –enable remi-php56

    # 4. 安装目标版本及常用扩展
    yum install -y php php-fpm php-cli php-common php-gd php-mbstring \\
    php-mysqlnd php-pdo php-xml php-json php-curl php-zip php-opcache

    # 5. 启动服务
    systemctl start php-fpm
    systemctl enable php-fpm
    systemctl restart nginx

    降到 7.3 则把 remi-php56 换成 remi-php73。

    3.3 PHP 7.4 升级命令(Remi 仓库)

    yum install -y epel-release
    yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
    yum install -y yum-utils

    yum-config-manager –enable remi-php74
    yum update -y php*

    Remi 装的 7.4 配置文件路径变了:

    文件路径
    php.ini /etc/opt/remi/php74/php.ini
    php-fpm.conf /etc/opt/remi/php74/php-fpm.conf
    pool 配置 /etc/opt/remi/php74/php-fpm.d/www.conf

    3.4 PHP 常用扩展与 MySQL 组件

    Remi 仓库版本切换 速查表

    命令作用
    yum-config-manager –enable remi-php56 启用 PHP 5.6 仓库
    yum-config-manager –enable remi-php73 启用 PHP 7.3 仓库
    yum-config-manager –disable remi-php74 关闭 PHP 7.4 仓库
    yum install -y php-<ext> 安装指定扩展(ext 如 gd/mbstring)
    yum update -y php* 按当前启用仓库升级全部 PHP 包

    扩展 速查表

    扩展作用
    php-mysqlnd MySQL 原生驱动(必装),提供 mysqli 与 pdo_mysql
    php-pdo PDO 数据库抽象层
    php-gd 图像处理(验证码、缩略图)
    php-mbstring 多字节字符串处理
    php-xml XML 处理
    php-curl HTTP 请求
    php-zip ZIP 压缩
    php-opcache 字节码缓存

    yum install -y php-cli php-common php-devel \\
    php-mysqlnd php-pdo \\
    php-gd php-mbstring php-xml php-bcmath \\
    php-json php-curl php-zip php-opcache

    ⚠️ 注意:不要装 php-pecl-mysql,它在 PHP 7 中已废弃,改用 mysqli 或 PDO_MySQL。

    四、MariaDB 安装与连接

    4.1 安装与安全初始化

    yum install -y mariadb mariadb-server
    systemctl start mariadb
    systemctl enable mariadb
    mysql_secure_installation

    mysql_secure_installation 按提示设置 root 密码、移除匿名用户、禁止 root 远程登录、删除 test 库。

    4.2 为 ECShop 创建数据库和用户

    CREATE DATABASE ecshop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE USER 'ecshop'@'localhost' IDENTIFIED BY 'ecshop_pass';
    GRANT ALL PRIVILEGES ON ecshop.* TO 'ecshop'@'localhost';
    FLUSH PRIVILEGES;

    4.3 PHP 连接测试

    cat > /website/ecshop/test_db.php << 'EOF'
    <?php
    $conn = new mysqli("localhost", "ecshop", "ecshop_pass", "ecshop");
    if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
    }
    echo "数据库连接成功";
    $conn->close();
    EOF

    访问后确认成功,测试完删除该文件。MariaDB 直接兼容 PHP 标准的 MySQL 扩展,无需专用「php-mariadb」包;推荐 php-mysqlnd,避免使用已废弃的 php-mysql。

    五、Session 与会话问题

    5.1 session_start(): open(…) failed: Permission denied(13)

    报错内容

    Warning: session_start(): open(/var/lib/php/session/sess_xxx, O_RDWR) failed:
    Permission denied (13) in /website/ecshop/install/index.php on line 23

    根因:PHP-FPM 运行用户对 /var/lib/php/session/ 目录没有写权限。

    ⚠️ 注意:Session 目录和 ECShop 项目目录是两回事,需分别处理——项目目录按第六章改属主,Session 目录单独改这里。

    ps aux | grep php-fpm # 确认 PHP-FPM 运行用户(如 nginx)
    chown -R nginx:nginx /var/lib/php/session
    chmod 700 /var/lib/php/session
    systemctl restart php-fpm

    5.2 连锁反应:Invalid argument supplied for foreach()

    Session 写入失败后,依赖 Session 的变量为空,导致 foreach 遍历空值报 Warning。Session 权限修复后,此警告通常自动消失。

    六、ECShop 目录权限问题

    6.1 安装检测大量目录「不可写」

    现象:安装向导检测结果中,cert、images、data、temp、themes/default/ 下所有 .dwt 和 .lbi 文件全部显示「不可写」。

    根因:PHP-FPM 运行用户既不是这些目录的属主,也不在允许写入的组里。ECShop 后台的模板编辑功能需要写 .dwt 和 .lbi 文件,所以这些文件必须对 PHP-FPM 用户可写。

    ⚠️ 注意:把整个 ECShop 目录属主统一为 PHP-FPM 用户是最省事的做法;Session 目录(第五章)要单独处理,不要一并 chown 到项目目录里。

    6.2 权限修复命令

    目录权限修复 速查表

    命令作用
    chown -R nginx:nginx /website/ecshop 递归改项目目录属主为 PHP-FPM 用户
    find /website/ecshop -type d -exec chmod 755 {} \\; 目录权限设为 755
    find /website/ecshop -type f -exec chmod 644 {} \\; 文件权限设为 644
    chmod -R 775 /website/ecshop/cert 可写目录放宽到 775

    chown -R nginx:nginx /website/ecshop

    find /website/ecshop -type d -exec chmod 755 {} \\;
    find /website/ecshop -type f -exec chmod 644 {} \\;

    chmod -R 775 /website/ecshop/cert
    chmod -R 775 /website/ecshop/images
    chmod -R 775 /website/ecshop/data
    chmod -R 775 /website/ecshop/temp
    chmod -R 775 /website/ecshop/themes

    systemctl restart php-fpm

    七、时区问题

    7.1 date(): It is not safe to rely on the system’s timezone settings

    报错内容

    Warning: date(): It is not safe to rely on the system's timezone settings.
    You are *required* to use the date.timezone setting or the date_default_timezone_set() function.
    …
    in /website/ecshop/includes/cls_mysql.php on line 161

    根因:PHP 未配置默认时区,调用 date() 时产生警告,打断 ECShop 安装数据流程。

    ⚠️ 注意:date.timezone 必须在 php.ini 配置,否则安装流程会被警告打断;临时在代码里加 date_default_timezone_set() 只是应急,重启 PHP 后仍可能复发。

    7.2 两种修法

    推荐(一劳永逸):改 php.ini 后重启服务。

    date.timezone = Asia/Shanghai

    systemctl restart php-fpm
    systemctl restart nginx

    临时:在 /website/ecshop/includes/cls_mysql.php 顶部 <?php 后加:

    date_default_timezone_set('Asia/Shanghai');

    八、YUM 源问题(CentOS 7 EOL 后更换源)

    CentOS 7 已于 2024-06-30 停止维护,官方镜像源失效。装包前先切源。

    方案一:华为云 EPEL 源

    mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.bak
    wget -qO /etc/yum.repos.d/epel.repo https://mirrors.myhuaweicloud.com/repo/epel-7.repo
    yum clean metadata
    yum makecache

    方案二:切换 CentOS Vault 归档源

    mkdir -p /etc/yum.repos.d/bak
    mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/

    cat > /etc/yum.repos.d/CentOS-Vault.repo << 'EOF'
    [base]
    name=CentOS-7.9.2009 – Base
    baseurl=https://repo.huaweicloud.com/centos-vault/7.9.2009/os/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://repo.huaweicloud.com/centos-vault/RPM-GPG-KEY-CentOS-7

    [updates]
    name=CentOS-7.9.2009 – Updates
    baseurl=https://repo.huaweicloud.com/centos-vault/7.9.2009/updates/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://repo.huaweicloud.com/centos-vault/RPM-GPG-KEY-CentOS-7

    [extras]
    name=CentOS-7.9.2009 – Extras
    baseurl=https://repo.huaweicloud.com/centos-vault/7.9.2009/extras/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://repo.huaweicloud.com/centos-vault/RPM-GPG-KEY-CentOS-7
    EOF

    yum clean all
    yum makecache

    九、证书问题

    9.1 导入 .crt 报 Import failed: Invalid value for field

    根因:导入的是只有公钥的 .crt 文件,缺少私钥信息;或自签名证书某些字段不符合 Windows 严格校验。

    解决

    需要部署到服务器:用 OpenSSL 合并为 .pfx:

    openssl pkcs12 -export -out www.zhb.cloud.pfx \\
    -inkey www.zhb.cloud.key -in www.zhb.cloud.crt

    只是让浏览器信任:导入到「受信任的根证书颁发机构」存储区。

    自签名证书 .crt 转 .pfx 流程:openssl 合并公私钥,两种用途对比

    十、其他问题

    10.1 Shell 引号嵌套导致 PHP 文件内容错误

    错误命令

    echo "<?=echo "php page"?>" > php_echo.php

    外层双引号与内层双引号冲突,Shell 解析错乱;且 <?= 本身等价于 echo,再写 echo 会变成 echo echo,PHP 语法错误。

    正确写法

    echo '<?= "php page" ?>' > php_echo.php

    或:

    echo '<?php echo "php page"; ?>' > php_echo.php

    十一、部署检查清单

    部署完逐项核对,避免上线后返工:

    ECShop 在 LNMP 上的部署检查清单可视化

    • Nginx root 写在 server 块顶层(不在 location 块内当默认 root)
    • fastcgi_param SCRIPT_FILENAME 在 include fastcgi_params; 之后
    • index 指令包含 index.php 且在最前
    • PHP-FPM 与 Nginx 用户一致,目录权限正确
    • /var/lib/php/session 属主为 PHP-FPM 用户且可写
    • ECShop 目录属主统一为 PHP-FPM 用户
    • cert、images、data、temp、themes 可写
    • php.ini 配置 date.timezone = Asia/Shanghai
    • MariaDB 已创建 ECShop 数据库与用户
    • php-mysqlnd、php-gd、php-mbstring 等扩展已安装
    • YUM 源已切换至可用镜像(EPEL 或 Vault)
    • PHP 版本与 ECShop 兼容(5.6 或 7.2/7.3)

    附:命令英文全称速查表

    命令 / 缩写英文全称 / 原意作用
    nginx engine x 高性能 Web 服务器 / 反向代理
    php-fpm PHP FastCGI Process Manager PHP FastCGI 进程管理器
    fastcgi Fast Common Gateway Interface 与 PHP 等后端通信的协议
    chown change owner 修改文件属主
    chmod change mode 修改文件权限
    session session(会话) 服务器端用户会话存储
    mariadb MariaDB(MySQL 分支,取名自创始人之女) 关系型数据库
    yum Yellowdog Updater Modified RPM 包管理器
    epel Extra Packages for Enterprise Linux 企业版 Linux 额外软件包
    Remi Rémi 的 RPM 仓库(命名自维护者 Rémi Collet) PHP 多版本仓库

    📚 参考资料(官方文档 · 中英双语)

    • Nginx ngx_http_fastcgi_module 手册
    • PHP 7.4 迁移指南:弃用的花括号语法
    • Remi 仓库官网
    • CentOS Vault 华为云镜像

    总结:ECShop 在 CentOS 7 + LNMP 上的报错,九成集中在「root 作用域 / index 指令 / PHP 版本 / 目录权限 / 时区」五件事。先把 root 提到 server 顶层、PHP 锁在 5.6 或 7.2/7.3、目录属主统一给 PHP-FPM 用户、php.ini 配好时区,再按第十一章清单逐项核对,基本一次就能跑通。你部署时还踩过哪些坑?评论区贴出报错一起看。

    赞(0)
    未经允许不得转载:171主机测评 » 一边装一边报错:CentOS 7 + LNMP 跑 ECShop 的常见故障与解法
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址