在Discuz插件开发中,数据库字段更新需要遵循X3.5特有的扩展机制。根据Discuz开发规范,建议通过以下步骤实现平滑升级:
1. 在插件目录创建update.php文件
通过$_G['setting']['pluginversion'][插件标识]获取当前版本号,使用版本号对比判断需要执行的更新操作:
- if($_G['setting']['pluginversion']['插件标识'] < '2.0') {
- $sql = <<<EOF
- ALTER TABLE `pre_plugin_table`
- ADD COLUMN `new_column` int(10) NOT NULL DEFAULT '0' COMMENT '新字段',
- MODIFY COLUMN `old_column` varchar(100) NOT NULL DEFAULT '' COMMENT '修改字段类型';
- EOF;
- runquery($sql);
- }
复制代码
2. 使用Discuz数据库操作类
推荐采用DB::query结合fetch_table_info方法实现字段存在性检测:
- $tableinfo = C::t('#插件标识#tablename')->fetch_table_info();
- if(!isset($tableinfo['fields']['new_column'])) {
- DB::query("ALTER TABLE ".DB::table('plugin_table')." ADD new_column int(10) NOT NULL DEFAULT '0'");
- }
复制代码
3. 字段删除注意事项
建议保留废弃字段至少三个版本周期,通过版本号控制延迟删除:
- if($_G['setting']['pluginversion']['插件标识'] < '2.3') {
- if(isset($tableinfo['fields']['deprecated_column'])) {
- DB::query("ALTER TABLE ".DB::table('plugin_table')." DROP COLUMN deprecated_column");
- }
- }
复制代码
4. 数据结构校验机制
在插件的check()方法中实现表结构校验:
- public function check() {
- $table = C::t('#插件标识#tablename');
- if(!$table->check_column('is_new_feature', 'TINYINT(1)')) {
- $table->add_column('is_new_feature', 'TINYINT(1) NOT NULL DEFAULT 0');
- }
- }
复制代码
5. 版本迭代记录
在plugin.xml中严格记录每个版本的数据结构变更:
- <version>2.0</version>
- <updatetime>2023-12-31</updatetime>
- <upgrade>增加用户行为追踪字段</upgrade>
复制代码
特别注意:
- 使用C::t()方法创建的数据表会自动继承Discuz的分表机制
- VARCHAR字段建议统一采用utf8mb4_unicode_ci排序规则
- 字段注释必须用英文描述,避免编码问题
- 涉及索引变更时需先DROP旧索引再创建新索引
我们DZ插件网技术团队建议采用增量升级方案,每个版本单独处理数据结构变更,同时保留完整的版本演进记录。如需获取更多开发资源,可访问DZ插件网开发者文档专区查阅最新技术指南。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。 |