苗Matrix 开发文档

开源社区论坛系统完整开发指南

一、系统架构

1.1 目录结构

yuanbbs/
├── admin/                  # 后台控制器
├── core/                   # 核心类库
│   ├── Database.php        # 数据库操作类
│   ├── YuanTemplate.php    # 模板引擎
│   └── Plugin.php          # 插件系统
├── forum/                  # 前台论坛控制器
├── include/                # 公共文件
│   ├── init.php            # 初始化文件
│   └── functions.php       # 公共函数库
├── member/                 # 用户中心控制器
├── plugin/                 # 插件目录
├── template/               # 主题模板目录
├── static/                 # 静态资源
├── cache/                  # 缓存目录
├── config.php              # 配置文件
├── index.php               # 首页入口
├── admin.php               # 后台入口
├── forum.php               # 论坛入口
└── member.php              # 用户中心入口

1.2 MVC架构说明

请求流程:
用户请求 → 入口文件(index.php/admin.php/forum.php/member.php)
         → 路由解析(?c=controller&a=action)
         → 控制器
         → 模型/数据库操作
         → 模板渲染
         → 输出响应

控制器命名规则:
- 文件名:XxxController.php(大驼峰)
- 类名:XxxController
- 方法名:小驼峰,如 index(), list(), edit()

示例URL:
- index.php?c=forum&a=index  → ForumController::index()
- admin.php?c=user&a=edit    → UserController::edit()

二、控制器开发

2.1 创建控制器

<?php
class ExampleController {
    public function index() {
        global $db, $template;
        
        $data = $db->select('table', '*', 'status = 1', array(), 'id DESC');
        
        $template->assign('title', '页面标题');
        $template->assign('data', $data);
        $template->display('example/index.html');
    }
    
    public function edit() {
        global $db, $template;
        
        $id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        
        if ($_POST) {
            $this->doEdit($id);
            return;
        }
        
        $item = $db->getOne('table', '*', 'id = ?', array($id));
        
        $template->assign('title', '编辑');
        $template->assign('item', $item);
        $template->display('example/edit.html');
    }
    
    private function doEdit($id) {
        global $db;
        
        checkCsrf();
        
        $name = trim($_POST['name']);
        
        if (empty($name)) {
            showMessage('名称不能为空', 'index.php?c=example&a=edit&id=' . $id);
        }
        
        $data = array(
            'name' => $name,
            'updated_at' => time()
        );
        
        if ($db->update('table', $data, 'id = ?', array($id))) {
            showMessage('更新成功', 'index.php?c=example');
        }
    }
}
?>

2.2 常用操作

// 获取全局变量
global $db;        // 数据库实例
global $template;  // 模板引擎实例
global $config;    // 系统配置

// 检查用户登录
checkLogin();      // 未登录跳转到登录页

// 检查管理员权限
checkAdmin();      // 非管理员拒绝访问

// CSRF防护(POST请求必须)
checkCsrf();       // 验证CSRF Token

// 显示消息并跳转
showMessage('操作成功', 'index.php');

// 获取当前用户信息
$user = $_SESSION['user'];
$uid = $_SESSION['user']['uid'];

// 分页处理
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$perpage = 20;
$pagination = pagination($total, $page, $perpage, 'index.php?c=example');

三、数据库操作

3.1 数据库API

// 查询单条记录
$user = $db->getOne('users', '*', 'uid = ?', array(1));

// 查询多条记录
$users = $db->select('users', 'uid, username, email', 'status = 1', array(), 'uid DESC', '0, 10');

// 统计记录数
$count = $db->count('users', 'status = 1', array());

// 插入记录
$insertId = $db->insert('users', array(
    'username' => 'test',
    'email' => 'test@example.com',
    'password' => passwordHash('123456'),
    'reg_time' => time()
));

// 更新记录
$affected = $db->update('users', array(
    'username' => 'newname',
    'updated_at' => time()
), 'uid = ?', array(1));

// 删除记录
$affected = $db->delete('users', 'uid = ?', array(1));

// 执行原生SQL
$results = $db->query('SELECT * FROM users WHERE uid > ?', array(0));

3.2 数据库表结构

users - 用户表
├── uid           - 用户ID(主键)
├── username      - 用户名
├── email         - 邮箱
├── password      - 密码(bcrypt加密)
├── group_id      - 用户组ID
├── status        - 状态(0禁用, 1正常, 2待激活)
├── reg_time      - 注册时间
└── last_login    - 最后登录时间

threads - 主题表
├── tid           - 主题ID
├── fid           - 版块ID
├── uid           - 作者ID
├── title         - 标题
├── content       - 内容
├── views         - 浏览数
├── replies       - 回复数
└── status        - 状态

posts - 回复表
├── pid           - 回复ID
├── tid           - 主题ID
├── uid           - 作者ID
├── content       - 内容
└── created_at    - 创建时间

forums - 版块表
├── fid           - 版块ID
├── name          - 版块名称
├── description   - 描述
├── parent_id     - 父版块ID
└── status        - 状态

四、模板引擎

4.1 模板语法

【变量输出】
                    - 输出变量
               - 输出对象属性/数组键
            - 输出数组元素
开发文档         - 带默认值的输出

【条件判断】
    请先登录

【循环遍历】

【包含模板】



    
    开发文档 - 苗Matrix
    


    
    
【调用函数】 【调用钩子】

4.2 控制器中操作模板

// 赋值变量到模板
$template->assign('title', '页面标题');
$template->assign('user', $userData);

// 显示模板
$template->display('forum/index.html');

五、插件开发

5.1 插件目录结构

plugin/hello_world/
├── plugin.info.php    # 插件信息(必需)
├── hooks.php          # 钩子实现(必需)
├── config.php         # 插件配置页面(可选)
├── install.php        # 安装脚本(可选)
├── install.sql        # 安装SQL(可选)
└── controllers/       # 自定义控制器(可选)

5.2 plugin.info.php 配置

<?php
return array(
    'name' => 'Hello World',
    'description' => '示例插件',
    'version' => '1.0.0',
    'author' => '苗Matrix',
    'enabled' => true,
    'hooks' => array('header_end', 'footer_start'),
    'config' => array(
        array(
            'name' => 'show_text',
            'title' => '显示文本',
            'type' => 'text',
            'default' => 'Hello!'
        )
    )
);
?>

5.3 hooks.php 钩子实现

<?php
if (!function_exists('hook_header_end')) {
    function hook_header_end($params = array()) {
        $config = Plugin::getConfig('hello_world');
        echo '<style>.hello-world{color:#667eea;}</style>';
    }
}
?>

5.4 插件API

// 获取插件配置
$config = Plugin::getConfig('hello_world');

// 更新插件配置
Plugin::updateConfig('hello_world', array('show_text' => 'New Text'));

// 检查插件是否启用
if (Plugin::isEnabled('hello_world')) {
    // 插件已启用
}

六、主题开发

6.1 主题目录结构

template/my_theme/
├── theme.info.php     # 主题信息(必需)
├── screenshot.png     # 主题截图(可选)
├── css/
│   └── style.css
├── js/
│   └── main.js
├── images/
├── common/
│   ├── header.html
│   └── footer.html
├── forum/
│   ├── index.html
│   └── thread.html
└── member/
    ├── login.html
    └── profile.html

6.2 theme.info.php 配置

<?php
return array(
    'title' => '我的主题',
    'description' => '一个现代化的论坛主题',
    'version' => '1.0.0',
    'author' => '苗Matrix',
    'thumbnail' => 'screenshot.png',
    'parent' => 'default',  // 父主题(可选)
    'settings' => array(
        array(
            'name' => 'primary_color',
            'title' => '主色调',
            'type' => 'color',
            'default' => '#667eea'
        )
    )
);
?>

七、钩子系统

7.1 可用钩子列表

钩子名称 位置说明 参数
header_end 页头结束位置
footer_start 页脚开始位置
login_form_bottom 登录表单底部
register_form_bottom 注册表单底部
admin_index 后台首页
thread_view_before 帖子内容前 thread: 帖子信息
thread_view_after 帖子内容后 thread: 帖子信息
user_login_after 用户登录后 user: 用户信息
thread_create_after 发帖后 tid: 主题ID

7.2 触发钩子

// 在控制器中触发钩子
hook_trigger('thread_create_after', array(
    'tid' => $tid,
    'uid' => $uid
));

// 在模板中放置钩子位置

八、公共函数库

8.1 安全函数

// CSRF防护
checkCsrf();              // 验证POST中的CSRF Token
checkCsrfGet();           // 验证GET中的CSRF Token
csrfToken();              // 获取当前CSRF Token
csrfField();              // 输出CSRF隐藏字段HTML

// 密码处理
passwordHash($password);  // 密码加密(bcrypt)
passwordVerify($password, $hash);  // 验证密码

// 输入验证
validateEmail($email);    // 验证邮箱格式
validateUrl($url);        // 验证URL格式

// 数据脱敏
maskEmail($email);        // 邮箱脱敏:t***@example.com
maskPhone($phone);        // 手机脱敏:138****8888

8.2 工具函数

// 时间处理
formatTime($time, 'Y-m-d H:i:s');  // 格式化时间戳
getRelativeTime($timestamp);       // 相对时间:刚刚、5分钟前

// 字符串处理
randomStr($length);                // 生成随机字符串

// 分页
pagination($total, $page, $perpage, $url);  // 生成分页HTML

// 消息提示
showMessage($message, $url);  // 显示消息并跳转

// 权限检查
checkLogin();     // 检查登录
checkAdmin();     // 检查管理员权限

// 邮件发送
sendMail($to, $subject, $content);  // 发送邮件

九、安全规范

9.1 SQL注入防护

// ✅ 正确:使用参数化查询
$user = $db->getOne('users', '*', 'uid = ?', array($uid));

// ❌ 错误:直接拼接SQL
$user = $db->query("SELECT * FROM users WHERE uid = $uid");

9.2 XSS防护

// ✅ 正确:输出时转义
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');

// ❌ 错误:直接输出
echo $userInput;

9.3 CSRF防护

// 表单中必须包含CSRF Token
<form method="post">
        ...
</form>

// 控制器中验证
public function save() {
    checkCsrf();  // 必须调用
    // ...
}

9.4 权限控制

// 后台控制器必须检查管理员权限
class AdminController {
    public function index() {
        checkAdmin();  // 非管理员拒绝访问
        // ...
    }
}

// 用户组权限
// group_id = 1: 超级管理员(所有权限)
// group_id = 2: 普通用户
// group_id = 3: 版主(前台管理权限)

十、配置说明

10.1 config.php 配置

<?php
return array(
    // 数据库配置
    'db' => array(
        'host' => 'localhost',
        'port' => 3306,
        'user' => 'root',
        'pass' => 'password',
        'name' => 'yuanbbs',
        'prefix' => 'yb_',
        'charset' => 'utf8mb4'
    ),
    
    // 网站配置
    'site' => array(
        'name' => '苗Matrix',
        'url' => 'https://example.com',
        'description' => '开源社区论坛系统'
    ),
    
    // 邮件配置
    'mail' => array(
        'smtp_host' => 'smtp.example.com',
        'smtp_port' => 465,
        'smtp_user' => 'noreply@example.com',
        'smtp_pass' => 'password',
        'smtp_secure' => 'ssl'
    ),
    
    // 模板配置
    'template' => array(
        'name' => 'default'
    ),
    
    // 开发模式
    'developer_mode' => false,
    'debug' => false
);
?>

10.2 开发模式

// 开启开发模式
'developer_mode' => true,

// 开发模式功能:
// 1. 支持外部目录开发插件和主题
// 2. 显示详细错误信息
// 3. 禁用模板缓存

十一、常见问题

Q: 模板修改后不生效?

清理模板缓存:删除 cache/template/ 目录下的所有文件,或在 config.php 中设置 'cache_enabled' => false

Q: 插件安装后不显示?

检查 plugin.info.php 中 'enabled' 是否为 true,检查钩子函数是否正确定义(使用 function_exists 检查)

Q: CSRF验证失败?

确保表单中包含 ,确保 session_start() 已在 include/init.php 中调用

Q: 数据库操作失败?

检查 config.php 中数据库配置是否正确,检查表前缀是否匹配

Q: 如何调试SQL语句?

开启 debug 模式后,SQL错误会显示详细信息。也可以使用 $db->query() 执行原生SQL进行调试