二次开发指南
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']; // 当前公众号ID9.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
最后编辑:周珊 更新时间:2026-05-05 23:04