菜鸟科技网

dedecms如何调用sql表?

基础用法:{dede:sql}

{dede:sql}标签是执行SQL并输出结果的核心,其基本语法如下:

dedecms如何调用sql表?-图1
(图片来源网络,侵删)
{dede:sql sql='你的SQL查询语句'}
    // 循环体内的代码,用于显示每一条查询结果
    [field:字段名/]
{/dede:sql}

参数说明

  • sql='' (必需参数)
    • 这是一个字符串,里面包含你要执行的完整SQL查询语句。
    • 注意:SQL语句必须用单引号 () 括起来,如果SQL语句本身包含单引号,需要进行转义(使用反斜杠 \)。

循环体内字段调用

{dede:sql}{/dede:sql}之间的代码块会根据查询结果的行数进行循环,在循环体内,使用[field:字段名/]来调用当前行的数据。

  • [field:id/]:调用查询结果中 id 字段的值。
  • [field:title/]:调用查询结果中 title 字段的值。
  • [field:字段名/]:调用任意你查询的字段。

实战示例

假设我们有一个自定义的表 dede_member_extra,用来存储会员的额外信息,表结构如下:

字段名 类型 说明
uid int(11) 会员ID (主键)
points int(10) 积分
realname varchar(50) 真实姓名
regdate int(10) 注册时间戳

示例1:查询积分最高的前5名会员

目标:在首页显示积分最高的5位会员的真实姓名和积分。

步骤:

dedecms如何调用sql表?-图2
(图片来源网络,侵删)
  1. 编写SQL语句

    SELECT uid, realname, points FROM dede_member_extra ORDER BY points DESC LIMIT 5
    • SELECT uid, realname, points:选择要查询的字段。
    • FROM dede_member_extra:从哪个表查询。
    • ORDER BY points DESC:按 points 字段降序排列。
    • LIMIT 5:只取前5条结果。
  2. 在模板中调用: 在你想要显示的模板文件(如 index.htm)中,添加以下代码:

    <h3>积分排行榜 TOP 5</h3>
    <ul>
      {dede:sql sql='SELECT uid, realname, points FROM dede_member_extra ORDER BY points DESC LIMIT 5'}
        <li>
          [field:realname/] - 积分: [field:points/]
        </li>
      {/dede:sql}
    </ul>

    效果:页面会输出一个列表,显示积分最高的5位会员的真实姓名和对应的积分。


进阶技巧与注意事项

处理带引号的字符串

如果你的SQL语句中包含单引号,比如查询某个特定姓名的会员:

SELECT * FROM dede_member_extra WHERE realname = '张三'

{dede:sql}标签中,需要将SQL语句内的单引号进行转义:

{dede:sql sql='SELECT * FROM dede_member_extra WHERE realname = \'张三\''}
    [field:realname/] 的积分是 [field:points/]
{/dede:sql}

安全性:使用@me进行变量替换(推荐)

当需要将外部变量(如栏目ID、文章ID等)传入SQL语句时,直接拼接字符串存在巨大的安全风险(SQL注入),DedeCMS提供了@me机制来安全地处理变量。

语法{dede:sql sql='... [field:varname/] ...'},其中varname是你通过globalarray传入的变量名。

示例:获取指定栏目ID下的文章总数。

步骤:

  1. 在模板中定义变量: 假设你通过PHP或其他方式获取了栏目ID $typeid = 5,并将其传递给模板,在模板中,你可以这样使用:

    {dede:sql sql='SELECT count(id) as c FROM dede_archives WHERE typeid = [field:typeid/]' typeid='5'}
      该栏目共有 [field:c/] 篇文章。
    {/dede:sql}
    • typeid='5':这里将值 5 赋给了模板变量 typeid
    • [field:typeid/]:在SQL语句中,这个标签会被替换为变量 typeid 的值,即 5

    更安全的做法(使用PHP变量): 在PHP文件中,你可以这样处理:

    // 在PHP文件中,index.php
    $typeid = 5;
    $tpl->Assign('typeid', $typeid);
    // ... 然后解析模板

    在模板中:

    {dede:sql sql='SELECT count(id) as c FROM dede_archives WHERE typeid = ~typeid~'}
      该栏目共有 [field:c/] 篇文章。
    {/dede:sql}

    (注意:这里使用了 ~typeid~ 的形式,这是一种更常见的变量替换方式,具体取决于DedeCMS的版本和配置。[field:typeid/] 的方式在某些特定场景下也有效。)

处理时间戳

如果你的表中存储的是Unix时间戳(如 regdate),直接输出是一串数字,你需要使用DedeCMS的日期格式化函数MyDate()来转换。

示例:显示会员的注册日期。

{dede:sql sql='SELECT uid, realname, regdate FROM dede_member_extra LIMIT 3'}
    <p>
      会员: [field:realname/] <br>
      注册时间: [field:regdate function='MyDate("Y-m-d H:i:s", @me)'/]
    </p>
{/dede:sql}
  • function='MyDate("Y-m-d H:i:s", @me)'
    • function:表示对字段值进行处理。
    • MyDate(...):调用DedeCMS内置的日期格式化函数。
    • "Y-m-d H:i:s":你想要的日期格式。
    • @me:代表当前字段的原始值(即时间戳)。

if 条件判断

你可以在循环体内使用 {if} 条件语句来实现更复杂的逻辑。

示例:如果积分大于1000,显示“VIP”标签。

{dede:sql sql='SELECT uid, realname, points FROM dede_member_extra LIMIT 5'}
    <li>
      [field:realname/]
      {if field:points > 1000}
        <span class="vip-tag">VIP</span>
      {/if}
      - 积分: [field:points/]
    </li>
{/dede:sql}

安全警告与最佳实践

  1. 禁止直接使用用户输入:绝对不要将用户通过表单提交的、未经任何过滤和转义的数据直接拼接到sql参数中,这是SQL注入攻击的主要入口。
  2. 最小权限原则:如果数据库用户有权限,确保它只拥有必要的权限,不要使用root或拥有ALL PRIVILEGES的用户来连接DedeCMS的数据库。
  3. 转义特殊字符:在必须拼接SQL时,对特殊字符(如单引号、双引号、反斜杠\等)进行转义。
  4. 使用预编译(如果可能){dede:sql}标签本质上是字符串拼接,无法做到真正的预编译,对于复杂的、涉及用户输入的查询,最好的方式是在PHP文件中编写查询逻辑,然后将处理好的数据通过DedeTag引擎传递给模板。

替代方案:在PHP文件中直接调用

对于非常复杂或对性能要求极高的查询,直接在PHP文件中操作数据库是更灵活、更高效的选择。

示例:在 index.php 中查询并显示排行榜。

// 引入必要的文件
require_once (dirname(__FILE__) . "/include/common.inc.php");
// 初始化一个数组来存储结果
$top_members = array();
// 编写SQL查询
$sql = "SELECT uid, realname, points FROM dede_member_extra ORDER BY points DESC LIMIT 5";
$dsql->SetQuery($sql); // 设置SQL查询
$dsql->Execute(); // 执行查询
// 循环获取结果
while($row = $dsql->GetArray())
{
    $top_members[] = $row;
}
// 将数据分配给模板
$GLOBALS['top_members'] = $top_members;
// 解析首页模板
// include dedeTemplets('index.htm');

然后在模板 index.htm 中,你可以这样使用:

<h3>积分排行榜 TOP 5 (PHP方式)</h3>
<ul>
  {dede:loop table='top_members'}
    <li>
      [field:realname/] - 积分: [field:points/]
    </li>
  {/dede:loop}
</ul>

(注意:这里使用了{dede:loop}标签来遍历一个已经存在的PHP数组,而不是直接执行SQL。)

方法 优点 缺点 适用场景
{dede:sql} 简单、快捷,无需修改PHP文件。 安全性较低,功能有限,性能稍差。 简单的、固定的数据查询,如调用配置、排行榜等。
PHP文件操作 最安全、最灵活、性能最好 需要修改PHP文件,对PHP编程有一定要求。 复杂的业务逻辑、涉及用户输入、高性能要求的场景。

对于大多数常规需求,熟练掌握{dede:sql}标签已经足够,但在处理敏感数据或复杂逻辑时,请务必优先考虑在PHP文件中处理,以确保网站的安全和稳定。

分享:
扫描分享到社交APP
上一篇
下一篇