二次开发指南

1. 代码规范

1.1 命名规范

类型 规范 示例
类名 大驼峰 (PascalCase) UserModel, WeixinAccount
函数名 下划线分隔 (snake_case) get_user_info(), pdo_fetch()
变量名 下划线分隔 (snake_case) $user_name, $order_id
常量名 全大写下划线分隔 ACCOUNT_TYPE_WXAPP, STATUS_ON
数据库表名 小写+下划线 ims_users, ims_mc_members
目录名 小写 framework/, addons/
文件名 小写+下划线/点 user.mod.php, login.ctrl.php

1.2 代码风格

  • 缩进:使用4个空格缩进
  • 换行:每个语句后换行
  • 大括号:使用K&R风格,左大括号不换行
  • 注释:复杂逻辑需要添加注释
  • PHP标签:只使用 <?php 开头,不使用 ?> 结尾

1.3 示例代码

<?php
defined('IN_IA') or exit('Access Denied');

/**
 * 类说明
 */
class ExampleClass {

    /**
     * 函数说明
     * @param string $param1 参数1说明
     * @param int $param2 参数2说明
     * @return array 返回值说明
     */
    public function exampleFunction($param1, $param2 = 0) {
        global $_W, $_GPC;

        if (empty($param1)) {
            return error(-1, '参数不能为空');
        }

        $result = pdo_get('table', array('field' => $param1));

        return $result;
    }
}

2. 开发流程

2.1 控制器开发 (Web端)

2.1.1 创建控制器文件

web/source/ 下创建控制器,例如 web/source/example/demo.ctrl.php

<?php
defined('IN_IA') or exit('Access Denied');

global $_W, $_GPC;
$do = $_GPC['do'];
$op = $_GPC['op'];

// 路由分发
if ($op == 'display') {
    // 列表页
    $list = pdo_fetchall("SELECT * FROM " . tablename('example'));
    include template('example/display');
} elseif ($op == 'post') {
    // 新增/编辑
    $id = intval($_GPC['id']);
    if (!empty($id)) {
        $item = pdo_get('example', array('id' => $id));
    }

    if ($_W['ispost']) {
        $data = array(
            'title' => $_GPC['title'],
            'content' => $_GPC['content'],
            'createtime' => TIMESTAMP,
        );

        if (empty($id)) {
            pdo_insert('example', $data);
        } else {
            pdo_update('example', $data, array('id' => $id));
        }

        message('操作成功', url('example/demo', array('do' => 'display')), 'success');
    }

    include template('example/post');
} elseif ($op == 'delete') {
    // 删除
    $id = intval($_GPC['id']);
    pdo_delete('example', array('id' => $id));
    message('删除成功', referer(), 'success');
}

2.1.2 创建模板文件

web/themes/default/ 下创建模板,例如 web/themes/default/example/display.html

{template 'common/header'}
<div class="panel panel-default">
    <div class="panel-heading">列表</div>
    <div class="panel-body">
        <table class="table">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>标题</th>
                    <th>创建时间</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                {loop $list $item}
                <tr>
                    <td>{$item['id']}</td>
                    <td>{$item['title']}</td>
                    <td>{php echo date('Y-m-d H:i', $item['createtime'])}</td>
                    <td>
                        <a href="{url 'example/demo', array('do' => 'post', 'id' => $item['id'])}">编辑</a>
                        <a href="{url 'example/demo', array('do' => 'delete', 'id' => $item['id'])}" onclick="return confirm('确定删除?')">删除</a>
                    </td>
                </tr>
                {/loop}
            </tbody>
        </table>
        <a href="{url 'example/demo', array('do' => 'post')}" class="btn btn-primary">新增</a>
    </div>
</div>
{template 'common/footer'}

2.2 控制器开发 (App端)

与Web端类似,在 app/source/ 下创建控制器,模板在 app/themes/

2.3 访问路由

URL格式:web/index.php?c=控制器目录&a=控制器名&do=操作

示例:

  • 列表页:web/index.php?c=example&a=demo&do=display
  • 新增页:web/index.php?c=example&a=demo&do=post

3. 模块开发

3.1 模块目录结构

addons/example/
├── manifest.xml      # 模块清单
├── module.php        # 模块主类
├── site.php          # 站点入口处理器
├── wxapp.php         # 小程序入口处理器
├── template/         # 模板目录
│   ├── display.html
│   └── ...
├── inc/              # 逻辑目录
│   ├── web/          # 后台逻辑
│   │   ├── demo.inc.php
│   │   └── ...
│   └── mobile/       # 移动端逻辑
├── icon-custom.jpg   # 模块图标
└── ...

3.2 模块清单文件 (manifest.xml)

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <application>
        <name><![CDATA[示例模块]]></name>
        <identifie>example</identifie>
        <version>1.0</version>
        <type>addons</type>
        <ability>
            <content><![CDATA[这是一个示例模块]]></content>
        </ability>
        <author><![CDATA[开发者]]></author>
        <url><![CDATA[http://www.example.com]]></url>
        <settings>1</settings>
    </application>
    <platform>
        <type>account</type>
        <type>wxapp</type>
    </platform>
    <permissions>
    </permissions>
</manifest>

3.3 模块主类 (module.php)

<?php
defined('IN_IA') or exit('Access Denied');

class ExampleModule extends WeModule {

    public function fieldsFormDisplay($rid = 0) {
        // 规则表单显示
    }

    public function fieldsFormValidate($rid = 0) {
        // 规则表单验证
    }

    public function fieldsFormSubmit($rid) {
        // 规则表单提交
    }

    public function ruleDeleted($rid) {
        // 规则删除
    }

    public function doWebDemo() {
        // 后台管理页
        global $_W, $_GPC;
        include $this->template('web/demo');
    }

    public function doMobileDemo() {
        // 移动端页面
        global $_W, $_GPC;
        include $this->template('mobile/demo');
    }
}

3.4 模块站点处理器 (site.php)

<?php
defined('IN_IA') or exit('Access Denied');

class ExampleModuleSite extends WeModuleSite {

    public function doWebDemo() {
        global $_W, $_GPC;
        // 后台管理逻辑
        include $this->template('web/demo');
    }

    public function doMobileDemo() {
        global $_W, $_GPC;
        // 移动端页面逻辑
        include $this->template('mobile/demo');
    }

    public function respond() {
        // 微信消息响应
        global $_W, $_GPC;
        $message = $this->message;

        // 处理文本消息
        if ($message['type'] == 'text') {
            return $this->respText('你好,这是示例模块的回复');
        }
    }
}

3.5 访问模块

  • 后台管理:web/index.php?c=site&a=entry&m=example&do=demo
  • 移动端:app/index.php?i=1&c=entry&a=site&do=demo&m=example

4. 数据库操作

4.1 创建数据表

在模块中创建安装SQL文件,如 addons/example/install.sql

CREATE TABLE IF NOT EXISTS `ims_example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uniacid` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `content` text,
  `createtime` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `uniacid` (`uniacid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

4.2 常用数据库操作

<?php
// 查询单条
$item = pdo_get('example', array('id' => 1));

// 查询多条
$list = pdo_fetchall("SELECT * FROM " . tablename('example') . " WHERE uniacid = :uniacid", array(':uniacid' => $_W['uniacid']));

// 插入
$data = array(
    'uniacid' => $_W['uniacid'],
    'title' => '测试',
    'content' => '内容',
    'createtime' => TIMESTAMP,
);
pdo_insert('example', $data);
$new_id = pdo_insertid();

// 更新
pdo_update('example', array('title' => '新标题'), array('id' => 1));

// 删除
pdo_delete('example', array('id' => 1));

// 统计
$count = pdo_fetchcolumn("SELECT COUNT(*) FROM " . tablename('example'));

4.3 分页查询

<?php
$pageindex = max(1, intval($_GPC['page']));
$pagesize = 10;

$sql = "SELECT * FROM " . tablename('example') . " WHERE uniacid = :uniacid ORDER BY id DESC LIMIT " . ($pageindex - 1) * $pagesize . "," . $pagesize;
$list = pdo_fetchall($sql, array(':uniacid' => $_W['uniacid']));

$total = pdo_fetchcolumn("SELECT COUNT(*) FROM " . tablename('example') . " WHERE uniacid = :uniacid", array(':uniacid' => $_W['uniacid']));
$pager = pagination($total, $pageindex, $pagesize);

5. 模板语法

5.1 变量输出

<!-- 输出变量 -->
{$variable}

<!-- 输出HTML -->
{php echo $content}

<!-- 调用函数 -->
{php echo date('Y-m-d', $time)}

5.2 条件判断

{if $status == 1}
    <span>开启</span>
{elseif $status == 2}
    <span>关闭</span>
{else}
    <span>未知</span>
{/if}

5.3 循环

{loop $list $index $item}
    <div>
        <span>第{$index}条:{$item['title']}</span>
    </div>
{/loop}

5.4 包含模板

{template 'common/header'}
<!-- 页面内容 -->
{template 'common/footer'}

5.5 URL生成

<a href="{url 'site/display', array('id' => $id)}">链接</a>

6. 提交规范

6.1 Git提交信息格式

<type>(<scope>): <subject>

<description>

Type类型:

  • feat:新功能
  • fix:修复bug
  • docs:文档更新
  • style:代码格式调整
  • refactor:重构
  • test:测试相关
  • chore:构建/工具相关

6.2 提交示例

fix(模块名): 修复用户登录超时问题

- 修复token验证逻辑
- 增加超时时间配置

6.3 代码提交前检查

  • 代码格式符合规范
  • 测试通过
  • 无调试代码(如var_dump, echo)
  • 无敏感信息
  • 更新相关文档

7. 扩展机制

7.1 钩子 (Hook)

系统支持钩子机制,可以在特定位置插入自定义代码。

7.2 支付接口扩展

参考 payment/weixin/ 目录结构创建新支付方式。

7.3 账号类型扩展

参考 framework/class/account/ 目录创建新账号类型。

7.4 模板主题扩展

web/themes/app/themes/ 下创建新主题目录。


8. 调试技巧

8.1 日志记录

<?php
// 记录日志
WeUtility::logging('debug', '调试信息');
WeUtility::logging('error', '错误信息', $data);

// 日志位置:data/logs/

8.2 变量输出

<?php
// 开发模式下使用
var_dump($variable);
exit;

// 或使用
print_r($variable);

8.3 查看SQL

<?php
// 开启SQL日志后在data/logs中查看
// 或直接输出
$sql = "SELECT * FROM " . tablename('users');
echo $sql;

9. 常见问题

9.1 如何添加后台菜单

web/source/system/menu.ctrl.php 中添加,或通过数据库直接插入 ims_core_menu 表。

9.2 如何获取当前用户信息

<?php
global $_W;
$user = $_W['user']; // 当前登录用户
$account = $_W['account']; // 当前账号
$uniacid = $_W['uniacid']; // 当前公众号ID

9.3 如何上传文件

<?php
load()->func('file');
$file = file_upload($_FILES['file'], 'image');
if (is_error($file)) {
    message($file['message']);
}
// $file['path'] 为文件路径

上一章:部署指南


开发手册完

作者:周珊  创建时间:2026-05-05 22:56
最后编辑:周珊  更新时间:2026-05-05 23:04