{dede:loop} 是 DedeCMS 中一个非常核心且强大的标签,它的作用是执行一个自定义的 SQL 查询,并将查询结果循环输出,相比于系统内置的固定循环标签(如 {dede:arclist}、{dede:channelartlist}),{dede:loop} 提供了极高的灵活性,让你可以自由地从数据库的任意表中获取数据。

(图片来源网络,侵删)
基本语法和结构
{dede:loop} 标签由两部分组成:开始标签、结束标签以及内部的字段调用标签。
{dede:loop table='数据表名' sort='排序字段' row='记录条数' if='查询条件'}
<!-- 循环体内,使用 [field:字段名/] 来调用当前记录的字段 -->
<li>
<a href="[field:link/]">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
</li>
{/dede:loop}
核心属性详解
| 属性名 | 说明 | 示例 |
|---|---|---|
table |
(必需) 指定要查询的数据表名,可以是 DedeCMS 的任意表(#@__archives, #@__arctype, #@__member 等),也可以是你自己创建的表。 |
table='#@__archives' |
sort |
指定排序的字段和方式。ASC 为升序,DESC 为降序,多个字段排序用逗号隔开。 |
sort='pubdate DESC' |
row |
指定要获取的记录条数。 | row='10' |
if |
(非常重要) 设置 SQL 查询的 WHERE 条件,你可以在这里写标准的 SQL 条件语句。 |
if="typeid=1 AND arcrank > -1" |
col |
指定要查询的字段,默认是 (所有字段),如果只查询需要的字段,可以提高查询效率。 | col="id,title,litpic" |
noself |
是否排除当前栏目(通常与 {dede:channelartlist} 配合使用时才有意义),在 loop 中不常用。 |
noself='yes' |
实战应用场景
{dede:loop} 的强大之处在于它能解决很多系统标签无法满足的需求。
场景1:调用指定栏目下的文章(比 arclist 更灵活)
假设你想调用 “产品中心” 栏目(ID=3)下的 10 篇文章,并按发布日期倒序排列。
方法:

(图片来源网络,侵删)
- 你需要知道文章表是
#@__archives,栏目ID字段是typeid。 - 使用
loop标签进行查询。
<h3>产品中心最新文章</h3>
<ul>
{dede:loop table='dede_archives' sort='pubdate DESC' row='10' if='typeid=3'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
</li>
{/dede:loop}
</ul>
说明:
table='dede_archives': 从文章表查询。if='typeid=3': 只查询栏目ID为3的文章。[field:arcurl/]: 这是一个特殊字段,DedeCMS 会自动将其解析为文章的完整链接。[field:title/]: 文章标题。function="MyDate(...)": 对日期字段进行格式化处理,这是 DedeCMS 模板内置的函数。
场景2:调用自定义表单的数据
这是 {dede:loop} 最经典的应用,假设你创建了一个“留言反馈”的自定义表单,数据保存在 dede_diyform1 表中,你想在首页显示最新的5条留言。
方法:
- 进入后台的【核心】->【内容模型管理】->【自定义表单】,找到你的表单(如“留言反馈”),点击“管理表单字段”,记下字段的名称(如
name,tel,content,time)。 - 在首页模板中使用
loop
<h3>最新留言</h3>
<div class="feedback-list">
{dede:loop table='dede_diyform1' sort='id DESC' row='5'}
<div class="feedback-item">
<p><strong>姓名:</strong>[field:name/]</p>
<p><strong>电话:</strong>[field:tel/]</p>
<p><strong>留言内容:</strong>[field:content/]</p>
<p><small>留言时间:[field:time function="MyDate('Y-m-d H:i:s',@me)"/]</small></p>
<hr>
</div>
{/dede:loop}
</div>
说明:

(图片来源网络,侵删)
table='dede_diyform1': 直接查询你的自定义表单数据表。[field:name/]、[field:content/]等直接调用你自定义表单中的字段名。sort='id DESC': 通常按自增ID倒序排列,即最新的在最前面。
场景3:调用会员信息并关联其发布的文章
假设你想调用注册时间最新的5位会员,并同时显示他们最近发布的一篇文章标题。
方法:
这需要关联查询 #@__member (会员表) 和 #@__archives (文章表)。
<h3>最新会员及他们的文章</h3>
<ul>
{dede:loop table='dede_member m left join dede_archives a on m.mid=a.mid' sort='m.regdate DESC' row='5'}
<li>
会员:[field:m.username/] - 注册时间:[field:m.regdate function="MyDate('Y-m-d',@me)"/]
{if field:a.id /}
<br>最近文章:<a href="[field:a.arcurl/]">[field:a.title/]</a>
{else /}
<br>该会员暂未发布文章。
{/if}
</li>
{/dede:loop}
</ul>
说明:
table='...': 这里写的是一个完整的 SQLJOIN语句,将会员表和文章表关联起来。sort='m.regdate DESC': 按会员表的注册时间倒序排列。field:m.username: 使用表名.字段名的方式来调用不同表中同名字段的值(如果会员表和文章表都有id字段,就必须这样指定)。{if field:a.id /} ... {else /} ... {/if}: 这是 DedeCMS 的条件判断语句,用来判断会员是否发布了文章(a.id存在,则说明有关联的文章)。
与 {dede:sql} 的区别
初学者常常会混淆 {dede:loop} 和 {dede:sql}。
| 特性 | {dede:loop} |
{dede:sql} |
|---|---|---|
| 用途 | 查询并循环输出数据。 | 执行任意 SQL 语句,可以查询、更新、删除等。 |
| 输出 | 必须配合 [field:字段名/] 在循环体内使用。 |
不直接输出,查询结果需要通过 GetOne() 或 GetArray() 等PHP函数在 php 代码块中处理。 |
| 安全性 | 相对安全,属性经过系统封装,能有效防止大部分SQL注入。 | 风险较高,直接写SQL语句,如果变量处理不当,极易发生SQL注入攻击。不推荐普通用户使用。 |
| 复杂度 | 适合简单的 SELECT 查询和循环展示。 |
适合需要执行复杂SQL操作(如多表关联、子查询、更新数据)的场景。 |
简单总结:
- 如果你的需求是 “从数据库里拿一批数据,然后在页面上循环显示出来”,请用
{dede:loop}。 - 如果你的需求是 “执行一个复杂的、需要返回结果集并手动处理的SQL查询”,才考虑使用
{dede:sql},并且要非常注意安全。
注意事项
- 性能问题:
{dede:loop}是直接操作数据库的,row值设置得过大,或者if条件复杂,或者频繁调用,会给数据库带来较大压力,影响网站速度,应尽量按需查询,避免SELECT *。 - 字段前缀:DedeCMS 的数据表默认有
#@__前缀,系统会自动替换为你在配置文件中设置的数据表前缀,所以直接写table='dede_archives'是可以的。 - 权限问题:确保你查询的表和字段,当前模板所在的栏目有足够的读取权限。
- 安全性:虽然
loop相对sql安全,但对于if属性中的变量(如从GET或POST获取的值),最好还是进行过滤或转义,防止恶意输入。
掌握 {dede:loop} 标签,意味着你拥有了在 DedeCMS 模板中自由获取和展示数据的能力,是进阶学习 DedeCMS 模板制作的关键一步。
