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';
} 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['client_type'] = $client_type;
其中,$thread
是即将写入数据库的数组,我们直接追加字段即可。
五、前端展示:在帖子详情页显示设备类型
Hook 文件:hook/thread_views_after.htm
<span class="text-muted"> · 来自
<?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 插件开发的精髓:小改动,大效果;低耦合,高复用。