Skip to content

开发—产品框架

1. MVC架构

1. 什么是MVC架构

MVC 是 Model-View-Controller 的缩写,是软件架构中的一种经典分层模式,其核心思想是:将业务逻辑(M)、界面展示(V)与请求控制(C)分离,从而实现代码解耦、职责清晰、易于维护和扩展。

层级 名称 职责说明
M(模型) Model 数据层:处理数据结构、数据库操作、业务逻辑,如获取用户、帖子、积分
V(视图) View 展示层:将数据渲染成前端界面,如 HTML 模板、JS
C(控制器) Controller 控制层:接收请求,调度模型与视图,如帖子详情逻辑控制、数据分页等

2. MVC主要解决的问题

问题 MVC 的解决方式
HTML/PHP 混杂、难维护 分离 V 与 C,模板与逻辑隔离
数据调用与控制逻辑耦合 Model 独立,统一封装数据访问
页面增改影响全局代码 Controller 层级分发,模块可独立开发
团队协作混乱(设计、开发分工) 前端关注 View,后端关注 M+C

3. Discuz! 如何体现 MVC 架构设计?

Discuz! 虽然不是严格的面向对象 MVC 框架(如 Laravel、Symfony),但它采用了 “文件路径级” 的轻量 MVC 实现,非常适合高性能需求场景。

  1. Model:数据层(位于 source/class/、function/)

  2. 所有数据库操作通过封装的 C::t() 调用数据表类,如:

C::t('forum_thread')->fetch($tid);  // 获取主题
C::t('common_member')->update($uid, $data);  // 更新用户
  • 传统函数式操作放在 source/function/function_*.php 中,如:
function getuserbyuid($uid) { return DB::fetch_first(...); }
  1. View:视图层(位于 template/)

  2. 所有前端页面结构使用 .htm 模板文件,如:

template/default/forum/viewthread.htm   // 主题阅读页模板
template/default/common/header.htm      // 站点头部模板
  • 模板变量通过 template::assign() 或 PHP 渲染注入:
<div class="user">{$member['username']}</div>
  • 支持多语言 {lang xxx}、条件判断 {if}、模板嵌套 {subtemplate} 等语法。

  • Controller:控制器层(位于 source/module/ 或 include/)

  • 控制器按模块划分(forum、portal、group 等):

source/module/forum/forum_viewthread.php  // 主题页控制器
source/module/member/member_login.php     // 登录控制器
  • 每个入口文件(如 forum.php)解析参数后引入具体控制器:
require libfile('function/forum');
require libfile('forum/viewthread', 'module');  // 加载 viewthread 控制器
  • 控制器中负责处理用户请求、调用模型、加载模板:
$thread = C::t('forum_thread')->fetch($tid);
include template('forum/viewthread');  // 渲染页面

4. 总结:Discuz! 的 MVC 架构实践特征

特性 实现方式
控制器路径分发 forum.php?id=viewthread → source/module/forum/forum_viewthread.php
模型类封装 source/class/table/table_xxx.php + C::t() 调用
模板系统 .htm + {} 语法 + template() 函数
轻量、文件驱动 不使用复杂 OOP,仅用路径、数组、函数组织逻辑
插件机制 插件挂钩点执行自有 C+V 逻辑,不改动核心

2. Discuz! 的目录架构

根目录文件夹 根目录文件

1. 根目录各文件夹功能总览

目录名 用途分类 功能说明
api/ 接口控制层 📌 Discuz! 与外部通信的 API 控制器,如 QQ 登录、UCenter 回调、支付网关等;访问入口为 api.php
archiver/ 纯文本归档 📄 提供论坛页面的纯 HTML 快速阅读版本,适合搜索引擎抓取及低流量展示;访问如:/archiver/tid-123.html
config/ 系统配置文件 🔧 存放数据库、UCenter 等全局配置文件,主要有 config_global.php 和 config_ucenter.php,安装过程中生成
data/ 可写运行数据 💾 运行期缓存、附件、模板编译结果、日志等全部写入此目录,必须具有写权限
install/ 安装逻辑入口 📦 Discuz! 安装程序目录(含 SQL 和页面),安装完成后应删除或限制访问;首次部署或升级执行此处逻辑
source/ 核心程序代码 🧠 主程序逻辑目录,包含控制器(forum、portal)、类库、插件、函数、语言包等,是 Discuz! 的 MVC 中枢
static/ 静态资源 🎨 存放全局静态文件,如 JS、CSS、默认图片等;模板通过 {STATICURL} 标签引用
template/ 前端模板 🧾 存放风格文件夹,每个目录对应一个模板套件;默认目录为 default/,可在后台切换风格
uc_client/ UCenter 客户端 🔗 与 uc_server 通信的 SDK(提供接口封装),用于登录、注册、同步登出等;供主程序调用
uc_server/ UCenter 服务端 🧩 独立运行的用户中心模块,支持跨站点统一用户认证、通信接口、积分同步、应用管理等

关键目录: source/: 逻辑核心目录,结构化清晰:

子目录 功能
admincp/ 后台控制器(如 setting、plugin 管理)
class/ 所有核心类库(分页、缓存、表单处理)
function/ 系统函数集合(如 function_core.php 为主入口)
include/ 前台模块调度逻辑入口,如论坛帖子展示逻辑
module/ 子模块细分控制器,如 module/forum/viewthread.php
plugin/ 插件系统注册与挂载逻辑
language/ 系统语言包,按模块划分,支持国际化
discuz_version.php 当前程序版本声明文件

data/: 运行期依赖目录(必须可写)

子目录 说明
attachment/ 上传的文件与图片
cache/ 存储全站配置、权限、导航、hook 缓存
template/ 生成的模板缓存 .tpl.php
log/ 错误日志和任务日志
threadcache/ 浏览缓存(纯文本),提高帖子响应速度
diy/ DIY 模块缓存
plugindata/ 插件缓存与配置数据
install.lock 安装锁,防止重复安装
update.lock 升级锁,避免脚本被二次运行
sendmail.lock 邮件频率限制锁文件

config/ 配置目录(初始化关键)

文件 说明
config_global.php ✅ 全站全局配置,数据库连接、缓存方式、路径配置、站点名等都在这里(必读)
config_ucenter.php ✅ UCenter 配置文件,包含通信密钥、接口地址
*_default.php 文件 📄 默认配置模板,用于初始化生成 config 文件

Discuz! 在安装阶段会根据 default 模板生成 config_global.php 与 config_ucenter.php,其中 $_config['db'] 与 $_config['cache'] 是插件开发、性能调优的重点配置对象。

install/ 安装系统目录

目录 说明
data/ 安装过程使用的 SQL 模板
include/ 安装控制器逻辑
static/ 安装界面用到的 CSS/JS

安装完成后应删除该目录或设置访问限制。

template/ 模板目录(前端展示)

目录 说明
default/ 默认风格模板目录(包含 forum_viewthread.htm 等)
index.htm 占位页

static/ 静态资源目录(前端 CSS/JS)

子目录 说明
js/ JS 脚本库(如 jQuery、common.js)
image/ 默认图片、图标、按钮
avatar/ 头像相关静态图标
topic/ / space/ 专题页和个人空间的样式资源

2. 根目录文件(站点入口级别)

文件/目录 说明
index.php 📌 Discuz! 前台主入口,论坛首页、门户、群组的调度入口(基于模块控制)
forum.php 📌 论坛页面入口(跳转至论坛首页、板块、主题页等)
portal.php 📌 门户系统入口(门户频道、文章、专题)
group.php 📌 群组系统入口
plugin.php 📌 插件系统前台入口:plugin.php?id=xxx 加载插件逻辑
member.php 📌 用户系统入口(登录、注册、找回密码)
search.php 📌 全站搜索入口
admin.php ⚠️ 后台管理中心入口(配合后台验证)
api.php 📌 第三方 API 接口控制入口(如 UCenter 回调)
connect.php 📌 QQ 登录 / 微信登录相关入口(依赖配置和插件)
robots.txt 🤖 搜索引擎爬虫限制策略文件

3. Discuz! X3.4 MVC 架构逻辑图

                    +----------------------+
                    |  用户请求 (浏览器)   |
                    +----------+-----------+
                               |
         请求路径如 forum.php?id=viewthread
                               |
                               v
              +-----------------------------+
              |  入口文件 (forum.php等)     |
              +-----------------------------+
                               |
                根据模块名加载控制器 (C层)
                               |
                               v
       +-------------------------------------------------+
       | 控制器文件:source/module/forum/forum_viewthread.php |
       +-------------------------------------------------+
                               |
                获取业务数据,调用模型类(M层)
                               |
                               v
       +------------------------------------------------+
       | 模型类(数据表类):                           |
       | source/class/table/table_forum_thread.php       |
       | 调用方式:C::t('forum_thread')->fetch($tid)     |
       +------------------------------------------------+
                               |
                  渲染视图,调用模板系统(V层)
                               |
                               v
         +-------------------------------------------+
         | 模板文件:template/default/forum/         |
         |           viewthread.htm                   |
         | 模板变量如:{$thread['subject']}           |
         +-------------------------------------------+

                              插件挂载点
                               |
            +------------------+------------------+
            | Hook 调用执行插件逻辑                |
            | 通过 source/plugin/ 加载控制器/模板 |
            +--------------------------------------+

说明:

  • 控制器(Controller):source/module/ 下的文件根据请求参数动态引入;
  • 模型(Model):数据层封装在 source/class/table/ 中,以 C::t('table_name') 调用;
  • 视图(View):模板文件位于 template/,支持语言包、模板变量、标签语法;
  • 插件机制通过 Hook 与模板嵌入,可无侵入扩展功能。

3. 自动加载

1. 什么是自动加载(Autoload)?

在传统 PHP 中,每次用到类都要 includerequire 文件,麻烦又易出错。
PHP 5+ 引入了 __autoload()spl_autoload_register(),允许自动加载类定义文件,Discuz! 正是利用这一机制构建类调用的“懒加载”系统。

2. Discuz!如何实现自动加载的?

位于 source/class/class_core.php 中(X3.4/3.5 均保留):

if(function_exists('spl_autoload_register')) {
    spl_autoload_register(array('core', 'autoload'));
} else {
    function __autoload($class) {
        return core::autoload($class);
    }
}

解释:

  • 注册一个自动加载回调函数:core::autoload();
  • 当你调用一个还没 include 的类时,PHP 会自动调用这个函数;
  • 如果类存在并命名规范,自动加载器会在 source/class/ 下找到它。

示例: 加载 discuz_table 类时无需手动 include

$table = new discuz_table();  // 自动加载 source/class/discuz/discuz_table.php

4. 核心文件 class_core.php 的作用

1. 位置及功能

source/class/class_core.php
功能 说明
注册自动加载器 spl_autoload_register(array('core','autoload'))
注册异常处理器 捕获 fatal error、抛出更友好的错误提示
初始化缓存内存机制 调用 discuz_memory 初始化 Redis / Memcache 等支持
定义简写类映射 class C extends core {} / class DB extends discuz_database {}
启动核心应用 discuz_application 框架主引导类,处理配置加载、数据库连接、用户 session 初始化等

2. C::t() 是什么?为什么常见?

这是 Discuz! 框架设计中的核心 “数据访问封装机制” ,用于操作**数据库表对象(Model层)** 。

C::t('forum_thread')->fetch($tid);  // 获取主题数据
C::t('common_member')->update($uid, array('credits' => 100));  // 更新用户积分

等价于:

$class = new table_forum_thread();
$class->fetch($tid);

原理:
- C 是 core 的别名类:class C extends core {};
- C::t() 会自动实例化并缓存指定表的数据类,如 table_forum_thread;
- 类文件位于:source/class/table/table_forum_thread.php;
- 继承自 discuz_table,内部封装了 DB::insert()、DB::fetch_first() 等操作。

简写类映射的意义(让代码更优雅)

在 class_core.php 中:

class C extends core {}  // 便于调用 C::t()、C::memory()
class DB extends discuz_database {}  // 快速调用数据库操作

这样可以写出:

C::t('forum_post')->insert(...);  // 代替 core::t()
DB::insert('forum_thread', $data);  // 代替 discuz_database::insert()

3. 类加载机制总结(请求流程)

用户访问 forum.php?id=viewthread
载入 class_core.php
注册自动加载器、内存系统、配置项
初始化 discuz_application(加载 config、env、setting)
通过 C::t() 加载模型类
调用 DB 封装的 SQL 操作
加载模板渲染输出

5. 数据库访问层(DB层)的设计与安全

目的 Discuz! 的实现方式
统一访问方式 引入 C::t('表名')->方法() 调用机制
避免直接 SQL 注入 格式化语法 + 安全处理器(如 %s, %d, %n)
模型层代码解耦 每个表一个 table_*.php 类,集中封装逻辑
插件调用不影响主系统 支持 C::t('#插件ID#表名') 结构调用插件表

对 insert()、update()、delete() 方法的处理逻辑

只有“数组形式”的参数会自动转义:

// 安全:自动处理
DB::insert('common_member', array('username' => 'admin', 'email' => 'x@x.com'));
// 不安全:开发者需自行处理
DB::query("INSERT INTO %t SET username='%s'", array('common_member', addslashes($name)));

C::t() 数据表类机制(标准调用模型)

项目 说明
每张表都有对应的 table_*.php 文件 位于 source/class/table/
类名以 table_表名 命名(不含前缀) 如 table_common_member
所有类都继承自 discuz_table 提供 fetch、insert、update 等基本操作
主键字段在类构造中通过 _pk 指定 无主键表需设置为 ''
通过 C::t('表名')->方法() 调用 统一接口风格,增强插件可移植性

实际使用示例:

// 获取单个用户
$user = C::t('common_member')->fetch($uid);

// 获取多个用户,以 uid 为 key
$list = C::t('common_member')->fetch_all(array(1,2,3));

// 插入记录
C::t('common_member')->insert(array('uid'=>123, 'username'=>'test'), false, true);

插件中如何使用 C::t()

Discuz! 支持插件私有的数据表类调用,方式如下:

项目
表名 mytablename(不带前缀)
所在路径 source/plugin/mypluginid/table/table_mytablename.php
类名 table_mytablename
调用方法 C::t('#mypluginid#mytablename')->method()

示例:

// 插件ID为 myplugin,表名为 mytablename
$data = C::t('#myplugin#mytablename')->fetch_by_uid($uid);

6. 模板机制

1. 模板加载机制(基于 template() 函数)

步骤 行为
1️⃣ 根据参数查找对应的模板文件路径:template/default/forum/viewthread.htm 或 .php
2️⃣ 检查是否已有缓存文件:data/template/*.tpl.php
3️⃣ 判断模板文件是否修改,若有修改则重新解析为 PHP 模板缓存
4️⃣ 返回已编译的 PHP 文件路径并执行
5️⃣ 模板文件中存在嵌套、变量、条件逻辑等,渲染最终 HTML

编译后的模板 PHP 文件放在:data/template/,可通过清除缓存强制刷新。

2. 模板文件格式支持:.htm 和 .php

  1. .htm 模板文件(默认)

  2. 放置于 template/default/ 或其他风格目录;

  3. 使用 {} 语法表示变量、控制结构、嵌套模板等;
  4. 需要由系统模板引擎编译为 .tpl.php 再执行。

  5. .php 模板文件(优先)

  6. 若模板目录下存在同名 .php 模板,将优先使用 .php;

  7. 仅需添加一行注释 <?php exit;?> 作为头部;
  8. 第二行及后面才是模板语法内容。
<?php exit;?>
<!--{eval echo '这是PHP模板';}-->

.php 模板允许嵌入原生 PHP,更适合高度定制化、低频调用页面(如错误页、管理面板)。

3. 模板语法详解

1. 变量输出

{$username}         <!-- 输出变量 -->
{$user['uid']}      <!-- 输出数组 -->

建议始终使用 {} 包裹变量,避免与原生 HTML 冲突。

2. 条件判断

<!--{if $is_admin}--> 欢迎管理员 <!--{/if}-->

<!--{if $score > 90}-->
  优秀
<!--{elseif $score > 60}-->
  及格
<!--{else}-->
  不及格
<!--{/if}-->

3. 循环语句

<!--{loop $posts $post}-->
  <div>{$post['author']}</div>
<!--{/loop}-->

<!--{loop $users $uid $user}-->
  <div>{$uid}: {$user['username']}</div>
<!--{/loop}-->

4. 模板嵌套

<!--{subtemplate common/header}-->   <!-- 编译时直接合并 -->
<!--{template common/footer}-->      <!-- 运行时 include 调用 -->

5. 插件钩子

Discuz 通过 Hook 插件机制允许开发者“注入前端模板 HTML 片段”。

<!--{hook/forumdisplay_top}-->

插件若注册此 Hook,在渲染模板时会将插件 HTML 内容自动插入此位置。

6. eval 原生 PHP 调用

<!--{eval $now = date('Y-m-d');}-->
<!--{eval echo $now;}-->

应谨慎使用 {eval},避免输出不可控变量,增加 XSS 风险。

7. 语言包调用

{lang index_yesterday}

Discuz 会自动从语言包文件加载对应文本:

  • 路径如:source/language/lang_template.php
  • 数据结构为:$lang['index_yesterday'] = '昨天';

4. 模板缓存机制

文件类型 说明
.htm 模板源文件 位于 template/ 目录,开发者编辑此文件
.tpl.php 缓存 位于 data/template/,自动生成的可执行 PHP 模板
缓存刷新 后台“更新缓存”或删除 data/template/ 手动刷新

Discuz 会自动比对 .htm 文件的修改时间,决定是否重新编译缓存。

5. 模板开发的实践规范建议

目标 建议做法
自定义页面风格 创建新模板目录,如 template/mytheme/,并在后台启用
插件输出样式自定义 使用 hook 模板片段 + 语言包分离
安全防护 禁止使用未过滤变量直接输出、eval 中使用外部数据
多语言支持 模板中只写 {lang xx},文字放入语言包文件
不要写逻辑到模板中 复杂判断应尽量放到控制器处理后传值过来

7. 缓存机制设计

1. 总体设计目标

目标 实现方式说明
提升页面访问性能 页面碎片、用户信息、帖子等热点数据缓存
减少数据库请求压力 使用内存级缓存优先读取,数据库为回源
支持灵活缓存策略 可选 file/sql/memcache/redis 等引擎
支持数据缓存自动同步 数据表类(Model)自动更新缓存项
插件可接入缓存机制 插件表类继承 discuz_table 即可接入缓存

2. 支持的缓存驱动类型(在 config_global.php 中配置)

$_config['cache']['type'] = 'file';     // 文件缓存(默认)
$_config['cache']['type'] = 'sql';      // 数据库缓存(小型站点)
$_config['cache']['type'] = 'memcache'; // 分布式 Memcache(需安装)
$_config['cache']['type'] = 'redis';    // 推荐方式,性能更好
驱动类型 推荐使用场景
file 默认,适合轻量环境
sql MySQL 直接缓存,性能差
memcache 多节点站点可选
redis ✅ 推荐,多站/分布式环境最优

3. 缓存实现的核心结构:discuz_memory 与 discuz_table

  1. discuz_memory:缓存控制类

文件位置:source/class/discuz/discuz_memory.php

实现了 Memcache/Redis/File/Sql 缓存操作的统一封装;
类似于缓存引擎适配器;
自动检测环境,按优先级选择可用驱动;
调用方式:

C::memory()->get('thread_123');        // 读取缓存
C::memory()->set('thread_123', $data); // 设置缓存
  1. discuz_table:数据表基类,模型级缓存入口

所有表类继承此类,例如:

class table_common_member extends discuz_table {
    protected $_table = 'common_member';
    protected $_pk    = 'uid';
    protected $_pre_cache_key = 'common_member_';
    protected $_cache_ttl = 600; // 缓存时间(秒)
}

内部机制:

属性名称 作用
$_pre_cache_key 缓存键前缀,例如 'common_member_'
$_cache_ttl 缓存时长,单位秒(如 600 秒)

4. discuz_table 中的缓存操作方法(自动 + 手动)

方法名 功能说明
fetch_cache($ids) 获取缓存(支持多个主键)
store_cache($id, $data) 存入缓存,指定 KEY
clear_cache($ids) 清除缓存
update_cache($id, $data) 更新缓存字段值
reset_cache($ids) 重置已有 key 的完整值
increase_cache($ids, $arr) 累加缓存中的字段值

说明:

当你调用 C::t('common_member')->fetch($uid),如果设置了缓存:

  • 会先从缓存中获取;
  • 若不存在,再查数据库,并写入缓存;
  • 更新(update())时,会自动同步更新缓存。

5. 插件表类同样可支持缓存

插件开发者只要按以下写法即可集成缓存机制:

// source/plugin/myplugin/table/table_mytablename.php
class table_mytablename extends discuz_table {
    protected $_table = 'plugin_mytable';
    protected $_pk = 'id';
    protected $_pre_cache_key = 'myplugin_mytablename_';
    protected $_cache_ttl = 300;
}

使用:

$data = C::t('#myplugin#mytablename')->fetch($id);       // 自动从缓存获取
C::t('#myplugin#mytablename')->update($id, $arr);        // 自动同步缓存

6. 缓存刷新机制与失效策略

场景 缓存是否自动更新
insert() 插入新数据 ❌ 需手动更新
update() 修改主键行 ✅ 自动更新
delete() 删除主键行 ✅ 自动清除
非主键字段变动影响逻辑 ❌ 需开发者手动清理或禁用缓存
自定义缓存如 store_cache 需自行控制

7. 缓存开发实践建议

目标 建议实现方式
性能优化热点数据表 启用 _pre_cache_key、合理设置 TTL
多页帖子避免缓存过多 仅缓存第一页(post_{$tid}_1)
插件表类接入缓存 继承 discuz_table 并设置缓存键
缓存清理 用 clear_cache() / update_cache()
页面片段缓存(视图层) 可使用 block 或插件缓存中间层

8. 后台页面开发

1. 后台页面开发的设计理念

Discuz! 的后台采用的是“模块化 + 权限校验 + 语言分离”的轻量 MVC 风格,其特点包括:

特性 实现机制
模块独立分发 每个 admincp_xxx.php 文件对应一个后台模块
安全检查机制 所有后台模块必须通过 IN_ADMINCP 校验
菜单自动识别与语言分离 所有菜单、按钮文字、提示均使用语言包
表单渲染自动化 使用 showsetting()、cpmsg() 等函数统一布局样式

2. 后台页面开发完整流程(X3.5 环境)

  1. 添加菜单项

文件: source/admincp/menu/menu_mynav.php
示例:

$menu['global'][] = array('menu_mynav_mytest', 'mynav_mytest');
$GLOBALS['admincp_actions_normal'][] = 'mynav';
  • 'menu_mynav_mytest' 是语言包 key;
  • 'mynav_mytest' 映射后台访问链接: admin.php?action=mynav&operation=mytest

  • 创建语言包

文件: source/language/lang_admincp_mynav.php

$extend_lang = array(
    'menu_mynav_mytest' => '我的测试功能',
);
  1. 创建后台逻辑控制器

文件: source/admincp/admincp_mynav.php

<?php
if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
    exit('Access Denied');
}

if($operation == 'mytest') {

    shownav('global', 'menu_mynav_mytest'); // 面包屑导航
    showsubmenu('我的功能标题');

    showformheader('mynav&operation=mytest');
    showtableheader('功能设置');

    showsetting('setting_basic_bbname', 'settingnew[bbname]', $setting['bbname'], 'text');
    showsetting('setting_basic_boardlicensed', 'settingnew[boardlicensed]', $setting['boardlicensed'], 'radio');

    showtablefooter();
    showsubmit('submit', 'submit');
    showformfooter();
}

3. 常用后台开发函数汇总(X3.5 全版本通用)

  1. 表单相关
函数 说明
showformheader() 输出
开头
showformfooter() 输出 结尾
showsetting() 输出一行表单项(文本、单选、多选等)
showhiddenfields() 输出
showsubmit() 输出提交按钮

示例:高级多选框

showsetting('setting_access_register_status', array('settingnew[regstatus]', array(
    array('open', $lang['setting_access_register_open']),
    array('invite', $lang['setting_access_register_invite'], 'showinvite'),
    $_G['setting']['connect']['allow'] ? array('connect', $lang['setting_access_register_connect'], 'showconnect') : array(),
)), $regstatus, 'mcheckbox');
  1. 表格与数据列表
函数 说明
showtableheader() 输出 开头 表格行
showtablerow() 输出
showtablefooter() 输出

示例:输出多行用户列表

showtableheader('用户列表');

foreach($userlist as $user) {
    showtablerow('', array('class="td25"', 'class="td28"'), array(
        '<input type="checkbox" name="delete[]" value="'.$user['uid'].'" />',
        '<input type="text" name="displayordernew['.$user['uid'].']" value="0" />',
        $user['username'],
    ));
}

showtablefooter();
  1. 页面结构与导航
函数 用途
shownav() 页面面包屑导航结构
showsubmenu() 二级菜单导航栏
  1. 消息提示
cpmsg('tasks_installed', 'action=tasks&operation=type', 'succeed');

参数说明:

参数 说明
'message' 语言包 key
'url' 跳转地址
'type' succeed, error, loadingform, download

4. 后台页面开发最佳实践建议

场景 建议
插件中使用后台页面 放入 source/plugin/yourid/admincp_*.php
添加后台菜单 使用 menu 文件 + 语言包自动识别机制
页面权限校验 强制判断 IN_ADMINCP 常量
语言多样性 所有显示文字必须从语言包提取
与表单结合存储配置 使用 C::config() 或 updatecache() 更新

5. 插件后台开发入口说明(补充)

插件后台页面逻辑文件可放在以下位置:

source/plugin/yourpluginid/admincp.inc.php          # 插件后台入口
source/plugin/yourpluginid/admin/setting.inc.php    # 后台分模块页面

插件调用后台页面的地址格式:

admin.php?action=plugins&operation=config&do=插件ID&identifier=插件ID&pmod=setting

6. 总结:Discuz! X3.5 后台开发机制核心优势

特性 实现方式
菜单注册 + 权限注册 menu_xxx.php + lang_admincp_xxx.php
表单构建自动化 showsetting()、showformheader() 等
安全机制完善 IN_ADMINCP 防止非法访问
插件扩展兼容性强 后台页面可独立挂载或作为核心模块扩展
UI一致性与自动语言 所有元素统一样式,支持多语言包