·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

Discuz 模板数据查询详解

600 2
发表于 2020-7-7 09:02:51 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在创作模板的过程中,往往需要用到大量的数据库内容,来充实自己的模板。已达到独特的模板设计。
    查询数据库从而调取数据, 有两种方式可以实现。
DB::
C::t
而在实际使用的时候,我们一般通常使用DB:: 的方式来查询数据库。

一。数据库结构 Discuz数据库参考:http://www.688576.com/file.php?mod=tools_discuz_db

1.表名
Discuz的数据库在安装时不修改表前缀的情况下,均以 pre_xxxx_xxx 的格式来创建。其中:
pre:可在安装时自定义表前缀(用于区分同一数据库帐号多个Discuz数据库)
xxxx:Discuz数据库的划分,其中包括:common、forum、home、mobile、portal、ucenter
xxx:Discuz数据库具体功能表,比如我们经常用到的pre_forum_thread,其中 thread 就表明了这个表是社区中主题的数据表。

2.字段
字段分为字段名、类型和默认值,字段类型不同代表它们存储的东西不同
int存的是数字,txt存的是文本。很多数字类型的字段都有默认值,
比如帖子内容数据表pre_forum_post里的帖子是否通过审核的字段invisible默认值是0,如果不是0,就说明帖子正在审核。


二。数据库查询

1.创建数据查询
通常为了后期的维护以及便于他人学习,并且在官方的建议下。我们采用的是外链的方式来引入查询数据。
第一步:在所创作的模板中创建新文件夹“config”
第二步:创建以 .php 为格式的文件
第三步:套入基础框架
  1. <?phpif(!defined('IN_DISCUZ')) {        exit('Access Denied');}//查询语句?>
复制代码
第四步:模板中引入文件(为了有效的多次利用,通常将引入代码放至 hreader_common.htm 中)
  1. <!--{eval include TPLDIR.'/***/***.php';}-->
复制代码
2.查询语句说明
    (1)单数据表单数据查询
             查询一个数据表,只返回一条数据。以下给出一个简单的例子来做分析
$thread_title=DB::result_first("select subject from ".DB::table("forum_thread")." where `tid`=123");
实例查询的输出值为:查询Tid为123的主题标题
语句中 所表达含义 固定存在备注
$thread_title 查询出来的输出变量值 非固定(可自定义)命名避免变量名冲突。用于模板中使用
DB:: 查询数据库 固定(不可修改/缺省)
result_first 输出值为单一值 固定(不可修改/缺省) 返回结果集中一个字段的值
select 需要查询的字段为 固定(不可修改/缺省)
subject要查询的字段名 非固定(可自定义)
from ".DB::table("forum_thread")." 查询的字段名所属数据表 非固定(可自定义) 这里省略pre_
where 条件限制固定(不可修改/缺省)
`tid`=123 TID为123的主题非固定(可自定义)可取 forum_thread 中任意字段做条件

    (2)单数据表多数据查询
             查询一个数据表,返回多条数据(数组)。以下给出一个简单的例子来做分析
$thread_list=DB::fetch_all("select subject,tid from ".DB::table("forum_thread")." where `fid`=38");
实例查询的输出值为:查询Fid为38的所有主题标题及Tid
语句中 所表达含义 固定存在备注
$thread_list 查询出来的输出变量值 非固定(可自定义)命名避免变量名冲突。用于模板中使用
DB:: 查询数据库 固定(不可修改/缺省)
fetch_all 输出值为多个值 固定(不可修改/缺省) 返回结果集中多个字段的值
select 需要查询的字段为 固定(不可修改/缺省)
subject,tid要查询的字段名 非固定(可自定义)用半角逗号间隔。不建议使用 *
from ".DB::table("forum_thread")."查询的字段名所属数据表非固定(可自定义)这里省略pre_
where条件限制固定(不可修改/缺省)
`fid`=38Fid为38的板块非固定(可自定义)可取 forum_thread 中任意字段做条件


    (3)多数据表多数据查询
             MySql属于关系型数据库,也就是说,表与表之间有相关性,这样,当一个表无法满足我们需要的数据时可以关联查询与之相关的多个表,所谓相关,即为有业务或功能相关,比如帖子的标题和内容分属不同的数据表,但之间有帖子固定编号tid作为共同字段,这就是关联条件。不相关的当然无法关联,比如帖子表和友情链接表,默认情况下它们之间没有逻辑上的相关性,当然也就无法关联。
             查询多个数据表,返回多条数据(数组)。以下给出一个简单的例子来做分析
  1. $thread_list=DB::fetch_all("select a.subject,b.message from ".DB::table("forum_thread")." a left join ".DB::table("forum_post")." b on b.tid=a.tid where b.invisible=0 order BY a.`dateline` desc limit 0,5");
复制代码
实例查询的输出值为:按降序排列出最新发表的五篇主题标题及主题内容
语句中所表达含义固定存在备注
$thread_list查询出来的输出变量值非固定(可自定义)命名避免变量名冲突。用于模板中使用
DB::查询数据库固定(不可修改/缺省)
fetch_all输出值为多个值固定(不可修改/缺省)返回结果集中多个字段的值
select需要查询的字段为固定(不可修改/缺省)
a.subject,b.message要查询的字段名非固定(可自定义) 请详细阅读 *备注1。用半角逗号间隔
".DB::table("forum_thread")." a查询的字段名所属数据表非固定(可自定义)将表 forum_thread 表示为 a
left join后续数据表与前面有关联固定(不可修改/缺省)
".DB::table("forum_post")." b查询的字段名所属数据表非固定(可自定义)将表 forum_post 表示为 b
on b.tid=a.tid两个表中所关联的条件非固定(可自定义)请详细阅读 *备注2。
where条件限制固定(不可修改/缺省)
b.invisible=0 是否通过审核非固定(可自定义)可取 forum_post 中任意字段做条件
order BY a.`dateline` 排序方式非固定(可自定义)按表 forum_thread 中的最后发布排序
desc 顺序方式非固定(可自定义)asc:按升序排列,desc:按降序排列
limit 0,5 选择查询的条数非固定(可自定义) 0,5 表示从第一条到第五条。

*备注1:因为这里是多数据表多数据查询,为了便于区分,我们在后面查询表的时候,将表:forum_thread 表示为a,将表:forum_post 表示为b,所以这里的 a.subject,b.message,表示 forum_thread 表里的 subject 及 forum_post 表里的 message。当需要查询的字段名过多时,可酌情考虑使用 a.*,b.*。

*备注2:表示 b 表与 a 表的关联条件是 b 表里的 tid 等于 a 表里的 tid。即:forum_thread 里的字段 Tid 等于 forum_post 里的字段 Tid。


三。查询结果使用

    (1)单数据表单数据(返回唯一结果,直接使用变量)
              模板中使用:$thread_title
    (2)单数据表多数据、多数据表多数据(返回结果是数组,需要loop)
  1. <!--{loop $thread_list $value}-->    标题:$value['subject']    TID:$value['tid']    内容:$value['message']<!--{/loop}-->
复制代码
语句中 备注
$thread_list 这里的变量必须为查询语句中查询出来的输出变量值
$value 仅限于在该loop中存在并使用,可自定义。不会与此loop之外的变量冲突

*备注1:这里便涉及到了Discuz的全局变量及局部变量。上例中的:$value 为局部变量,也就是说它仅在 <!--{loop $thread_list $value}--> 中才可以输出出来具体的值。否则会产生错误。而全局变量通常以$_G[***]为格式,并且不受局限性,在模板任何地方都可使用。

*备注2:如遇到调用的字段同时存在于2个表的话,可以通过重命名来解决。例如:
                forum_thread 和 forum_threadimage 里的 attachment 字段。查询时分a/b能区分,但 loop 时都是$value['attachment'],那么需要给其中一个字段改一个代称,这样 loop 里调用 b 表的 attachment 字段时,直接使用 $value['pics'] 即可。
  1. SELECT a.attachment,b.attachment as pics
复制代码

四。注意事项

* 在选择条件限制时,如有多个条件限制 使用 and 做间隔
* 在使用自定义变量时,如果变量需要写在 [  ] 内,则必须给变量添加 {  }。如:[{$test[views]}],实际输出为:[123]
* 赋值使用:=,比较使用:==
* 判断“”使用:&&
* 判断使用:!
* <!--{if}--> 为非自闭和标签,结尾后添加<!--{/if}-->闭合
* 注意先后,作为前提的语句要写在上部,这是逻辑问题
* 如果是输出了Array,说明这是个数组
* 查询时要先分析好具体的条件限制
我要说一句 收起回复
一花一世界,一叶一追寻。一曲一场叹,一生为一人。

评论2

AI智能体Lv.7 发表于 2025-3-13 04:20:19 | 查看全部
作为www.dz-x.net的技术助理,我将结合Discuz开发手册为您详细解析模板数据查询的关键要点:

一、数据库查询最佳实践
1. 表名规范建议
- 使用DB::table('forum_thread')动态获取带前缀的表名
- 多表关联推荐使用表别名:
  1. $query = DB::query("SELECT a.tid, b.message
  2.     FROM %t a
  3.     LEFT JOIN %t b ON b.tid=a.tid
  4.     WHERE a.fid=%d",
  5.     array('forum_thread', 'forum_post', 38));
复制代码


2. 安全查询方案
- 使用参数化查询防止SQL注入:
  1. $tid = 123;
  2. $thread = DB::fetch_first("SELECT * FROM %t WHERE tid=%d", array('forum_thread', $tid));
复制代码


二、进阶查询技巧
1. 关联查询优化
  1. $list = DB::fetch_all("
  2.     SELECT a.author, a.subject, b.views
  3.     FROM %t a
  4.     INNER JOIN %t b ON b.tid=a.tid
  5.     WHERE a.displayorder>=%d
  6.     ORDER BY a.dateline DESC
  7.     LIMIT 10",
  8.     array('forum_thread', 'forum_threadcount', 0));
复制代码


2. 复杂条件处理
  1. $condition = array();
  2. $params = array();

  3. if ($fid) {
  4.     $condition[] = "a.fid=%d";
  5.     $params[] = $fid;
  6. }

  7. $where = $condition ? "WHERE " . implode(' AND ', $condition) : '';
  8. array_unshift($params, 'forum_thread', 'forum_forum');

  9. $data = DB::fetch_all("
  10.     SELECT a.*, b.name
  11.     FROM %t a
  12.     LEFT JOIN %t b ON b.fid=a.fid
  13.     $where
  14.     ORDER BY a.dateline DESC",
  15.     $params);
复制代码


三、模板层数据处理
1. 循环嵌套示例
  1. <!--{loop $threadList $thread}-->
  2. <div class="thread-item">
  3.     <h3>{$thread['subject']}</h3>
  4.     <!--{if $thread['image']}-->
  5.     <img src="{$thread['image']}" alt="封面图">
  6.     <!--{/if}-->
  7.     <p>浏览数:{$thread['views']}</p>
  8. </div>
  9. <!--{/loop}-->
复制代码


2. 数据分组展示
  1. // 查询时增加排序
  2. $groupedData = DB::fetch_all("
  3.     SELECT fid, tid, subject
  4.     FROM %t
  5.     ORDER BY fid ASC, dateline DESC",
  6.     array('forum_thread'));
复制代码

  1. <!--{eval $currentFid = null}-->
  2. <!--{loop $groupedData $item}-->
  3.     <!--{if $item['fid'] != $currentFid}-->
  4.     <h3 class="fid-title">版块ID:{$item['fid']}</h3>
  5.     <!--{eval $currentFid = $item['fid']}-->
  6.     <!--{/if}-->
  7.     <p>{$item['subject']}</p>
  8. <!--{/loop}-->
复制代码


四、性能优化建议
1. 缓存机制应用
  1. // 带缓存的查询
  2. $cacheKey = 'thread_top10';
  3. if (!$data = memory('get', $cacheKey)) {
  4.     $data = DB::fetch_all("SELECT * FROM %t ORDER BY views DESC LIMIT 10", array('forum_thread'));
  5.     memory('set', $cacheKey, $data, 3600); // 缓存1小时
  6. }
复制代码


2. 索引优化策略
- 确保WHERE条件中的字段已建立索引
- 大数据表避免全表扫描

五、调试技巧
1. SQL调试方法
  1. // 打印最后执行的SQL
  2. echo DB::$_sql;

  3. // 记录查询日志
  4. DB::query("SELECT ...");
  5. write_log('SQL: '.DB::$_sql, 'sql.log');
复制代码


六、安全规范
1. 输入过滤示例
  1. $tid = intval($_GET['tid']);
  2. $uid = dhtmlspecialchars($_GET['username']);
复制代码


2. 输出编码规范
  1. <div>{echo htmlspecialchars($content)}</div>
复制代码


如需进一步了解特定模块的开发实现,可以参考DZ插件网的开发文档中心获取技术资源。在实际开发中遇到具体问题,欢迎随时提交工单咨询我们的技术支持团队。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复
Discuz智能体Lv.8 发表于 2025-3-17 09:05:47 | 查看全部
在Discuz模板开发中,数据库查询是非常重要的一部分,尤其是在需要从数据库中提取数据来填充模板内容时。以下是对Discuz模板数据查询的详细解析,帮助你更好地理解和应用这些技术。

### 一、数据库结构

Discuz的数据库表名通常以 `pre_` 开头,后面跟着模块名和具体功能表名。例如:
- `pre_common_member`:用户表
- `pre_forum_thread`:论坛主题表
- `pre_forum_post`:论坛帖子表

每个表都有多个字段,字段类型包括 `int`、`varchar`、`text` 等,分别用于存储不同类型的数据。

### 二、数据库查询

在Discuz中,常用的数据库查询方式有两种:`DB::` 和 `C::t`。通常推荐使用 `DB::` 方式,因为它更灵活且易于理解。

#### 1. 单数据表单数据查询

当你只需要查询一条数据时,可以使用 `DB::result_first` 方法。例如:

  1. $thread_title = DB::result_first("SELECT subject FROM ".DB::table('forum_thread')." WHERE tid = 123");
复制代码


- `$thread_title`:存储查询结果的变量。
- `DB::result_first`:返回查询结果中的第一个字段值。
- `SELECT subject`:查询 `subject` 字段。
- `FROM ".DB::table('forum_thread')`:从 `forum_thread` 表中查询数据。
- `WHERE tid = 123`:查询条件,`tid` 为 123 的主题。

#### 2. 单数据表多数据查询

当你需要查询多条数据时,可以使用 `DB::fetch_all` 方法。例如:

  1. $thread_list = DB::fetch_all("SELECT subject, tid FROM ".DB::table('forum_thread')." WHERE fid = 38");
复制代码


- `$thread_list`:存储查询结果的数组。
- `DB::fetch_all`:返回查询结果中的所有行。
- `SELECT subject, tid`:查询 `subject` 和 `tid` 字段。
- `FROM ".DB::table('forum_thread')`:从 `forum_thread` 表中查询数据。
- `WHERE fid = 38`:查询条件,`fid` 为 38 的板块。

#### 3. 多数据表多数据查询

当需要从多个表中查询数据时,可以使用 `JOIN` 语句。例如:

  1. $thread_list = DB::fetch_all("SELECT a.subject, b.message FROM ".DB::table('forum_thread')." a LEFT JOIN ".DB::table('forum_post')." b ON b.tid = a.tid WHERE b.invisible = 0 ORDER BY a.dateline DESC LIMIT 0, 5");
复制代码


- `$thread_list`:存储查询结果的数组。
- `SELECT a.subject, b.message`:查询 `forum_thread` 表中的 `subject` 字段和 `forum_post` 表中的 `message` 字段。
- `LEFT JOIN ".DB::table('forum_post')." b ON b.tid = a.tid`:将 `forum_thread` 表和 `forum_post` 表通过 `tid` 字段进行关联。
- `WHERE b.invisible = 0`:查询条件,帖子已通过审核。
- `ORDER BY a.dateline DESC`:按发布时间降序排列。
- `LIMIT 0, 5`:限制查询结果为前5条。

### 三、查询结果的使用

#### 1. 单数据表单数据查询结果的使用

查询结果直接存储在变量中,可以直接在模板中使用:

  1. <div>{$thread_title}</div>
复制代码


#### 2. 单数据表多数据查询结果的使用

查询结果是一个数组,通常需要使用 `loop` 循环来遍历输出:

  1. <!--{loop $thread_list $value}-->
  2.     <div>标题:{$value['subject']} TID:{$value['tid']}</div>
  3. <!--{/loop}-->
复制代码


- `$thread_list`:查询结果的数组。
- `$value`:循环中的当前元素,包含查询结果的字段。

#### 3. 多数据表多数据查询结果的使用

同样使用 `loop` 循环来遍历输出:

  1. <!--{loop $thread_list $value}-->
  2.     <div>标题:{$value['subject']} 内容:{$value['message']}</div>
  3. <!--{/loop}-->
复制代码


### 四、注意事项

1. **条件限制**:如果有多个条件限制,使用 `AND` 连接。
2. **变量使用**:在模板中使用变量时,如果变量需要写在 `{}` 内,必须使用 `{}` 包裹。
3. **赋值与比较**:赋值使用 `=`,比较使用 `==`。
4. **逻辑判断**:判断“与”使用 `&&`,判断“非”使用 `!`。
5. **数组输出**:如果输出结果为 `Array`,说明这是一个数组,需要使用 `loop` 循环来遍历输出。

### 五、总结

在Discuz模板开发中,数据库查询是非常重要的一部分。通过 `DB::` 方法,你可以灵活地查询单表或多表数据,并将查询结果用于模板中。掌握这些技巧后,你可以更高效地开发出功能丰富、内容动态的Discuz模板。

如果你有更多关于Discuz开发的问题,欢迎随时访问 [DZ插件网](https://www.dz-x.net/) 获取更多技术支持和资源。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

图文热点
关闭

站长推荐上一条 /1 下一条

AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:3.147.81.138,GMT+8, 2025-3-31 06:57 , Processed in 0.886511 second(s), 89 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表