杰瑞科技汇

ECSOP二次开发教程从哪开始学?

ECShop 是一款经典的 PHP 开源网店系统,虽然其官方更新已放缓,但由于其稳定、易用和庞大的用户基础,至今仍有大量网站在使用,二次开发可以让你在不破坏其核心逻辑的前提下,添加新功能、修改现有行为,以满足个性化需求。

ECSOP二次开发教程从哪开始学?-图1
(图片来源网络,侵删)

第一部分:ECShop 开发环境准备

在开始之前,你需要一个本地开发环境,推荐使用集成环境包,它们可以一键配置好 PHP、MySQL、Web 服务器等。

软件安装

  • Web 服务器: Apache (ECShop 对 Apache 的 Rewrite 规则支持更好) 或 Nginx。
  • PHP 版本: 强烈推荐 PHP 7.1 或 7.2,ECShop 的早期版本对 PHP 8.x 的支持不佳,会出现大量兼容性问题,新项目应尽量使用高版本 PHP,但 ECShop 二次开发通常需要迁就旧版本。
  • 数据库: MySQL 5.6+ 或 MariaDB。
  • 集成环境包:
    • Windows: XAMPP, WampServer, phpStudy
    • macOS: MAMP, XAMPP
    • Linux: 可以使用 apt (Ubuntu/Debian) 或 yum (CentOS) 安装 LAMP (Linux, Apache, MySQL, PHP) 环境。

安装 ECShop

  1. 从 ECShop 官方网站或可靠源下载 ECShop 安装包(ecshop4.1.0 版本)。
  2. 将下载的文件解压,并将 upload 文件夹内的所有文件和文件夹通过 FTP 或 SFTP 工具上传到你的 Web 服务器根目录(htdocswww)。
  3. 创建一个新的数据库和数据库用户,并记录下数据库名、用户名和密码。
  4. 在浏览器中访问你的域名,http://localhost/
  5. 按照安装向导的提示进行操作,填写数据库信息、管理员信息等。
  6. 安装成功后,务必删除 install 文件夹,这是出于安全考虑。

代码编辑器

选择一款好的代码编辑器能极大提高开发效率,推荐:

  • Visual Studio Code (VS Code): 免费、强大、插件丰富。
  • Sublime Text: 轻量、快速。
  • PhpStorm: 专业 PHP IDE,功能最全面,但收费。

第二部分:ECShop 核心架构与目录结构

理解 ECShop 的“骨架”是二次开发的关键。

目录结构解析

ECShop 的目录结构清晰,遵循 MVC 思想的雏形。

ECSOP二次开发教程从哪开始学?-图2
(图片来源网络,侵删)
ecshop/
├── admin/              # 后台管理程序目录
│   ├── templates/      # 后台模板文件
│   └── ...             # 后台 PHP 控制文件
├── upload/             # 核心业务逻辑目录 (重要!)
│   ├── includes/       # 核心函数库和类库
│   │   ├── lib_base.php      # 基础函数库 (常用函数)
│   │   ├── lib_goods.php     # 商品相关函数
│   │   ├── lib_user.php      # 用户相关函数
│   │   ├── cls_ecshop.php     # ECSHOP 核心类
│   │   └── ...               # 其他核心库
│   ├── modules/        # 各个功能模块的 PHP 控制器
│   │   ├── goods/       # 商品模块
│   │   ├── user.php     # 用户模块
│   │   └── ...          # 其他模块
│   └── languages/      # 语言包目录
│       ├── zh_cn/       # 简体中文语言包
│       └── ...          # 其他语言
├── data/               # 缓存和数据目录
│   ├── cache/          # 系统缓存
│   └── ...             # 其他数据文件
├── images/             # 图片资源目录
├── themes/             # 前端模板目录
│   └── default/        # 默认模板
├── api/                # API 接口目录
├── index.php           # 前台入口文件
├── admin.php           # 后台入口文件
└── ...                 # 其他文件

核心运行流程

  1. 入口文件: index.phpadmin.php 是程序的入口。
  2. 初始化: 入口文件会加载 includes/init.php,这个文件是整个系统的初始化脚本,负责加载核心类、常量、数据库连接等。
  3. 路由分发: 系统会根据 URL 参数(如 act=user, op=login)来决定调用哪个模块的哪个方法。
    • act (Action): 通常对应 modules/ 下的一个文件,如 act=user -> modules/user.php
    • op (Operation): 对应 user.php 文件中的某个函数,如 op=login -> user.php 中的 login() 函数。
  4. 模型-视图-控制器 (MVC雏形):
    • C (Controller - 控制器): modules/ 下的 PHP 文件,负责接收请求、调用业务逻辑、处理数据。
    • M (Model - 模型): 主要指 includes/lib_*.php 中的函数和类,负责数据的增删改查和业务逻辑计算。
    • V (View - 视图): themes/ 下的模板文件,负责展示数据。

第三部分:二次开发实战教程

下面通过几个常见的二次开发场景,来讲解具体的开发方法。

修改首页的某个区域(如“热卖商品”)

目标: 将首页的“热卖商品”模块修改为“新品上架”模块。

步骤:

  1. 找到模板文件:

    ECSOP二次开发教程从哪开始学?-图3
    (图片来源网络,侵删)
    • 首页模板位于 themes/default/index.dwt
    • 用编辑器打开这个文件,搜索 {foreach from=$hot_goods item=goods},这个 foreach 循环就是渲染“热卖商品”的代码块。
  2. 找到数据来源:

    • index.dwt 中,通常在文件顶部或 {insert_scripts} 标签之前,会有一句类似 {insert name='top10'} 的代码,这就是插入“热卖商品”数据的钩子。
    • 这个 insert 标签对应的处理函数在 includes/lib_insert.php 文件中,找到 function insert_top10() 函数,你会发现它查询的是 ecs_goods 表中 is_hot = 1 的商品。
  3. 修改数据逻辑:

    • 我们不直接修改 lib_insert.php,因为这样会影响到其他可能使用“热卖商品”的地方,更好的方法是复制并重命名这个函数。

    • lib_insert.php 中,复制 insert_top10() 函数,重命名为 insert_new10()

    • 修改新函数中的 SQL 查询条件,将 is_hot = 1 改为 is_new = 1

      // 在 lib_insert.php 中
      function insert_new10($arr)
      {
      $time = gmtime();
      $sql = "SELECT goods_id, goods_name, goods_img, shop_price, market_price " .
             "FROM " . $GLOBALS['ecs']->table('goods') .
             " WHERE is_new = 1 AND is_delete = 0 AND is_on_sale = 1 AND goods_id > 0 " .
             "ORDER BY goods_id DESC LIMIT " . $arr['num'];
      $res = $GLOBALS['db']->getAll($sql);
      $goods_list = array();
      foreach ($res AS $idx => $row)
      {
          $goods_list[$idx]['id']          = $row['goods_id'];
          $goods_list[$idx]['name']        = $row['goods_name'];
          $goods_list[$idx]['thumb']       = get_image_path($row['goods_id'], $row['goods_img']);
          $goods_list[$idx]['url']         = build_uri('goods', array('gid'=>$row['goods_id']), $row['goods_name']);
          $goods_list[$idx]['price']       = price_format($row['shop_price']);
      }
      return $goods_list;
      }
  4. 修改模板文件:

    • 回到 themes/default/index.dwt
    • {foreach from=$hot_goods item=goods} 改为 {foreach from=$new_goods item=goods}
    • {insert name='top10' assign='hot_goods'} 改为 {insert name='new10' assign='new_goods'}
  5. 清除缓存:

    • 访问网站后台 -> 商店设置 -> 清除缓存,或者直接删除 data/cache/ 目录下的所有文件。
    • 刷新首页,你就能看到“新品上架”了。

添加一个新的数据库表并管理它

目标: 添加一个“优惠券”表,并在后台管理它。

步骤:

  1. 创建数据表:

    • 通过 phpMyAdmin 或其他数据库管理工具,在你的 ECShop 数据库中执行以下 SQL 语句:
      CREATE TABLE `ecs_coupons` (
      `coupon_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '优惠券ID',
      `coupon_name` varchar(255) NOT NULL COMMENT '优惠券名称',
      `coupon_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '类型:0-满减,1-折扣',
      `coupon_value` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '优惠值(满减金额或折扣率)',
      `min_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '最低消费金额',
      `start_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '开始时间',
      `end_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '结束时间',
      `is_enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用',
      PRIMARY KEY (`coupon_id`)
      ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  2. 创建后台管理文件:

    • admin/ 目录下创建一个新文件 coupon.php
    • coupon.php 的基本结构:
      <?php
      define('IN_ECS', true);
      require(dirname(__FILE__) . '/includes/init.php');
      $action = !empty($_REQUEST['act']) ? trim($_REQUEST['act']) : 'list';

    // //-- 列表页面 // if ($action == 'list') { $smarty->assign('ur_here', $_LANG['coupon_list']); $smarty->assign('action_link', array('text' => $_LANG['add_coupon'], 'href' => 'coupon.php?act=add'));

    // 从数据库获取优惠券列表
    $coupons = get_coupon_list();
    $smarty->assign('coupons', $coupons);
    $smarty->display('coupon_list.htm');

    } // //-- 添加优惠券 // elseif ($action == 'add') { if (isset($_POST['submit'])) { // 处理表单提交,插入数据库 $sql = "INSERT INTO " . $ecs->table('coupons') . " (coupon_name, coupon_type, coupon_value, min_amount, start_time, end_time) VALUES ('".$_POST['coupon_name']."', ".$_POST['coupon_type'].", ".$_POST['coupon_value'].", ".$_POST['min_amount'].", ".$_POST['start_time'].", ".$_POST['end_time'].")"; $db->query($sql); // 跳转到列表页 ecs_header("Location: coupon.php?act=list\n"); exit; } $smarty->assign('ur_here', $_LANG['add_coupon']); $smarty->assign('action_link', array('text' => $_LANG['coupon_list'], 'href' => 'coupon.php?act=list')); $smarty->display('coupon_info.htm'); } // //-- 获取优惠券列表的函数 // function get_coupon_list() { $sql = "SELECT * FROM " . $GLOBALS['ecs']->table('coupons') . " ORDER BY coupon_id DESC"; return $GLOBALS['db']->getAll($sql); } ?>

  3. 创建后台模板文件:

    • admin/templates/ 目录下创建 coupon_list.htm (列表页) 和 coupon_info.htm (添加/编辑页)。
    • coupon_list.htm (列表页):
      {include file="pageheader.htm"}
      <div class="list-div" id="listDiv">
      <table cellpadding="3" cellspacing="1">
      <tr>
      <th>ID</th>
      <th>优惠券名称</th>
      <th>类型</th>
      <th>优惠值</th>
      <th>最低消费</th>
      <th>操作</th>
      </tr>
      {foreach from=$coupons item=coupon}
      <tr>
      <td>{$coupon.coupon_id}</td>
      <td>{$coupon.coupon_name}</td>
      <td>{if $coupon.coupon_type == 0}满减{else}折扣{/if}</td>
      <td>{$coupon.coupon_value}</td>
      <td>{$coupon.min_amount}</td>
      <td><a href="coupon.php?act=edit&id={$coupon.coupon_id}">编辑</a> | <a href="javascript:;" onclick="if(confirm('确定删除吗?')) location.href='coupon.php?act=drop&id={$coupon.coupon_id}'">删除</a></td>
      </tr>
      {/foreach}
      </table>
      </div>
      {include file="pagefooter.htm"}
    • coupon_info.htm (添加页): 需要创建一个表单,包含优惠券名称、类型、优惠值等字段。
  4. 添加菜单项:

    • 登录后台,在数据库的 ecs_admin_menu 表中添加一条记录,指向你的新管理页面。
    • parent_id 为 2 (商品相关),linkcoupon.php?act=listtext优惠券管理

修改前台用户注册流程

目标: 在用户注册时增加一个“手机号”字段,并验证其唯一性。

步骤:

  1. 修改数据库表:

    • ecs_users 表中增加一个 mobile 字段。
      ALTER TABLE `ecs_users` ADD `mobile` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '手机号' AFTER `user_name`;
  2. 修改注册模板:

    • 打开 themes/default/user_passport.dwt
    • 在用户名和密码输入框之间,添加手机号输入框。
      <li>
      <label for="mobile">手机号:</label>
      <input type="text" name="mobile" id="mobile" size="25" />
      </li>
  3. 修改注册处理逻辑:

    • 打开 modules/passport.php
    • 找到 register() 函数,在函数中,处理完 $_POST 数据后,在插入数据库之前,增加手机号的验证逻辑。
      // 在 passport.php 的 register() 函数中
      if (isset($_POST['mobile']) && !empty($_POST['mobile']))
      {
      // 验证手机号格式
      if (!preg_match('/^1[3-9]\d{9}$/', $_POST['mobile']))
      {
          show_message('手机号格式不正确', '', '', 'error');
      }
      // 验证手机号是否已存在
      $sql = "SELECT user_id FROM " . $GLOBALS['ecs']->table('users') . " WHERE mobile = '" . $_POST['mobile'] . "'";
      if ($GLOBALS['db']->getOne($sql))
      {
          show_message('该手机号已被注册', '', '', 'error');
      }
      // 将手机号存入 $user 数组,准备插入数据库
      $user['mobile'] = $_POST['mobile'];
      }
      // ... 后续的 $db->autoExecute 代码会将 $user 数组中的数据插入到 users 表

第四部分:高级技巧与注意事项

使用钩子

ECShop 的 insert 标签就是一个简单的钩子系统,你可以利用它在不修改核心文件的情况下,在模板的指定位置插入自定义内容。

覆盖核心文件

ECShop 的文件加载顺序是:先加载 themes/当前模板名/ 下的文件,如果没有再加载根目录下的同名文件。

  • 应用: 你想修改 includes/lib_goods.php 中的某个函数,但又不想动核心文件,你可以直接在 themes/default/includes/ 目录下创建一个 lib_goods.php 文件,并把需要修改的函数复制过去进行修改,系统会优先加载你的版本。

安全性

  • SQL 注入: 永远不要直接拼接 SQL 语句,ECShop 提供了 $GLOBALS['db']->getOne(), $GLOBALS['db']->getAll() 等安全查询方法,如果必须拼接,请使用 $ecs->table() 来获取表名,并始终对用户输入进行过滤。
  • XSS 跨站脚本: 在输出用户到页面的内容时(如商品名、评论),使用 htmlspecialchars() 函数进行转义,ECShop 的 $_CFG['lang'] 中有时会定义转义函数。
  • 文件上传: 严格控制上传目录的执行权限,并对上传的文件类型、大小、内容进行严格检查。

缓存机制

ECShop 大量使用缓存(data/cache/ 目录下的 .php 文件),修改了数据或配置后,如果前台或后台没有立即更新,请务必清除缓存,这是 ECShop 开发中最常见的问题之一。

调试技巧

  • 开启错误报告: 在 includes/init.php 的开头添加 error_reporting(E_ALL);ini_set('display_errors', 'On');,可以显示 PHP 的所有错误和警告,对排查问题非常有帮助。
  • 使用 print_r()die(): 在 PHP 代码中,使用 print_r($variable); die(); 来打印变量的内容并停止脚本执行,是快速查看变量值的简单方法。

第五部分:学习资源与社区

  • ECShop 官方论坛: 虽然官方已不主推,但论坛里仍有大量历史问题和解答。
  • 各种 ECShop 二次开发博客/教程站: 搜索“ECShop 二次开发 教程”可以找到很多个人博客的经验分享。
  • GitHub: 搜索 ecshop,可以找到一些基于 ECShop 的二次开发项目或补丁。

ECShop 的二次开发核心在于理解其目录结构MVC雏形数据流向,从修改模板开始,到操作数据库,再到编写复杂的业务逻辑,遵循“先看,再改,后重构”的原则,多练习,多分析现有代码,你就能逐渐掌握它。

在修改任何核心文件之前,先备份!这是所有开发工作的黄金法则。

分享:
扫描分享到社交APP
上一篇
下一篇