Xiuno BBS 开发实践教程 — 6 — 改造现有系统之增加列实现自己所需功能
Tillreetree (99) 开发者 管理团队 8小时前

Xiuno BBS 开发实践教程 - 改造现有系统之增加列实现自己所需功能

零、前置知识要求

请先阅读并理解《Xiuno BBS 开发实践教程 - 网站大事记》,因为你将直接操作数据库表结构,并使用 db_ 系列函数。

同时需掌握基本的 PHP、HTML、MySQL 以及 Xiuno BBS 的 hook 机制。

一、需求

我们希望在每个帖子详情页中显示:该帖子是由用户通过什么设备发布的(如网页端、iOS、Android、微信小程序等)。

这不仅能增强社区的互动感,还能为后续的数据分析(如用户终端分布)提供基础。

二、为什么选择直接修改 thread 表?

你可能会问:为什么不新建一张表(如 bbs_thread_client)来存储设备信息?

答案是:简单、高效、符合 ORM 设计

Xiuno BBS 的“ORM”(即 db_ 系列函数)在读取 thread 表时,会自动返回所有字段的关联数组。

只要我们在 bbs_thread 表中新增一列,thread_read()thread_find() 等函数就会自动包含该字段,无需额外 JOIN 查询(且Xiuno BBS也提供的数据库函数没有join功能),也无需修改核心 Model 逻辑。并且还能利用缓存机制更高效(因为 thread 本身已被缓存,使用thread_read_cache即可获得缓存里的帖子信息),而且当删除帖子的时候,新增列的数据也会随着消失,数据一致性高(与帖子生命周期一致)。

三、数据库变更:新增 client_type 字段

1. SQL 语句设计

ALTER TABLE bbs_thread ADD COLUMN client_type VARCHAR(50) DEFAULT '' COMMENT '用户发帖设备类型';

注意:表前缀 {tablepre} 不一定是 bbs_,需动态获取。请继续看下去。

2. 插件安装文件 install.php

<?php
!defined('DEBUG') AND exit('Forbidden'); // 不允许直接访问

$tablepre = $db->tablepre;// 表前缀

$sql = "ALTER TABLE {$tablepre}thread ADD COLUMN client_type VARCHAR(50) DEFAULT '' COMMENT '用户发帖设备类型'"; // 准备SQL 

db_exec($sql); // 执行

3. 插件卸载文件 unstall.php

是的,文件名确实是 unstall.php,这是 Xiuno BBS 的约定。

<?php
!defined('DEBUG') AND exit('Forbidden'); // 不允许直接访问

$tablepre = $db->tablepre;// 表前缀

$sql = "ALTER TABLE {$tablepre}thread DROP COLUMN client_type"; // 准备SQL 

db_exec($sql); // 执行

提示:生产环境中建议先检查列是否存在,避免重复执行报错。但在教学插件中可简化处理。

四、业务逻辑:在发帖时自动识别设备类型

我们利用hook 机制,在帖子创建前插入设备识别逻辑。

Hook 文件:hook/thread_create_thread_before.php

// 获取用户代理字符串
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';

$client_type = 'web'; // 默认为网页端

$client_type = 'unknown';

if (strpos($ua, 'android') !== false) {
    $client_type = 'android';
} elseif (strpos($ua, 'iphone') !== false || strpos($ua, 'ipad') !== false) {
    $client_type = 'ios';
} elseif (strpos($ua, 'windows phone') !== false) {
    $client_type = 'windows_phone'; // RIP 微软移动端战略
} elseif (strpos($ua, 'micromessenger') !== false) {
    if (strpos($ua, 'miniprogram') !== false) {
        $client_type = 'mini-program';
    } else {
        $client_type = 'wechat'; // 微信内置浏览器
    }
} elseif (strpos($ua, 'mobile') !== false) {
    $client_type = 'mobile';
} elseif (strpos($ua, 'windows') !== false || strpos($ua, 'macintosh') !== false || strpos($ua, 'linux') !== false) {
    $client_type = 'web';
}

// 注入到即将插入数据库的 $thread 数组中
$thread['client_type'] = $client_type;

其中,$thread是即将写入数据库的数组,我们直接追加字段即可。

五、前端展示:在帖子详情页显示设备类型

Hook 文件:hook/thread_views_after.htm

<span class="text-muted"> &middot; 来自 
<?php
$client_type_map = [
    'web' => '网页端',
    'ios' => 'iPhone客户端', 
    'android' => '安卓客户端',
    'windows_phone' => 'Windows Phone', 
    'mini-program' => '微信小程序',
    'wechat' => '微信浏览器',
    'mobile' => '移动端',
    'unknown' => '未知设备'
];

// 安全兜底:防止未定义键
$display_type = isset($client_type_map[$thread['client_type']]) ?  $client_type_map[$thread['client_type']] :  $client_type_map['unknown'];
?>
</span>

六、插件目录结构

  • my_thread_clienttype/
    • conf.json
    • install.php
    • unstall.php
    • hook/
      • thread_create_thread_before.php
      • thread_views_after.htm

conf.json内容:

{
    "name": "帖子设备标识",
    "brief": "教学用插件。在帖子中显示用户发帖所用设备类型",
    "version": "1.0.0",
    "bbs_version": "4.0.4",
    "installed": 0,
    "enable": 0,
    "hooks_rank": [],
    "overwrites_rank": [],
    "dependencies": []
}

结语

通过本教程,你学会了:

  • 如何安全地修改 Xiuno BBS 核心表结构
  • 如何利用 hook 机制无侵入式扩展业务逻辑
  • 如何让新增字段自动融入现有 ORM 体系

这正是 Xiuno BBS 插件开发的精髓:小改动,大效果;低耦合,高复用

最新回复 (0)
广告推荐
Tillreetree
开发者 管理团队
广告推荐