帝国CMS用久了,后台的“管理数据表”列表从十几张变成上百张,每次建个模型都要翻半天,更头疼的是,自定义模型建好了,前台列表页死活不显示数据;灵动标签里写SQL总是报错;搜个东西还老是缺字段,这些问题的根源,往往不在模板标签本身,而在于你对数据表分组结构的理解是否透彻。
帝国CMS的数据表设计有一个核心特点:主表与附表分离,主表(如phome_ecms_news)存储常用字段和索引,附表(如phome_ecms_news_data_1)存储大文本、多行字段等,所谓“分组优化”,不是让你去改表结构,而是要在模型管理里,合理规划字段放在主表还是附表,从而在查询性能与调用便利性之间找到平衡。
自定义模型建好后,前台列表页空白
帝国CMS二次开发深水区,数据表分组优化的底层逻辑与实战排查手册
刚建了“产品库”模型,添加了3条数据,但用[!show.list]或者灵动标签调用,前台什么都出不来,排查步骤:
- 检查系统模型ID与数据表绑定:后台->系统设置->数据表管理,确认你新建的模型是否已“生成”数据表,如果只建了模型没点“生成数据表”,那数据根本没地方存。
- 检查字段是否分配到了主表:进入模型->管理字段,看你的“产品名称”字段,其“所属表”是“主表”还是“附表”,如果字段全在附表,而你在列表页只查询了主表,自然查不到数据。
- 输出调试SQL:在灵动标签里临时加一个参数
[!show.list]是万能标签,但如果你用自定义SQL,可以在模板里写如下代码强制查看SQL语句:
<?php
$sql = "SELECT * FROM `{dbprefix}}ecms_product` WHERE 1=1 LIMIT 10";
$empire->useclass = true;
$disp = $empire->query($sql);
while($r = $empire->fetch($disp)){
echo $r['title'].'<br>';
}
?>
如果这个能输出数据,说明主表有数据,若为空,检查你添加数据时,是否勾选了“发布到主表”选项。
灵动标签SQL调用的“致命陷阱”
灵动标签([!show.list])确实强大,但很多人写SQL时忘记加表前缀占位符,帝国CMS的灵动标签里,表名不能写死,要用{dbprefix}},正确写法:
[!show.list]select * from {dbprefix}}ecms_product where classid=5 order by newstime desc limit 10[/!show.list]
如果你的模型是自定义的,并且字段在附表,你必须用LEFT JOIN:
SELECT p.*, d.content FROM {dbprefix}}ecms_product p LEFT JOIN {dbprefix}}ecms_product_data_1 d ON p.id=d.id WHERE p.classid=5 LIMIT 10
注意:附表表名后缀是_data_1,这个数字是数据表ID,如果不知道,后台数据表管理里能看到。
列表模板和内容模板的变量调用差异
列表页用[!--title--]标签调用标题,内容页也想用同样方式调用自定义字段,结果输出空白,原因在于:列表页是从主表循环输出,内容页则默认查了主表+当前模型附表。
- 列表模板调用主表字段:
[!--title--]、[!--newstime--],若要调用附表字段,必须用灵动标签或SQL,因为列表查询默认只查主表,模板**内调用附表字段:直接使用[!--字段名--]即可,但有个前提,这个字段在模型设置里必须勾选“前台可调用”。
产品价格字段price在附表里,内容模板这样写:
价格:[!--price--]元
如果在列表页想显示价格,不能直接写[!--price--],必须用灵动标签:
[!show.list]select * from {dbprefix}}ecms_product p left join {dbprefix}}ecms_product_data_1 d on p.id=d.id where p.classid=1 limit 10
<a href="[!--titleurl--]">[!--title--]</a> - [!--price--]元
[/!show.list]
万能标签vs智能标签,别用错地方
- 万能标签(
[!show.list]):自由度极高,可以写任意SQL,适合跨模型调用、复杂统计,缺点是需要自己处理分页参数。 - 智能标签(
[!show.list_auto]):只需指定mid(模型ID)和cid(栏目ID),系统自动生成SQL,适合单模型、简单列表。
使用场景举例:全站最新文章,如果只调一个模型,用智能标签:
[!show.list_auto]mid=1,cid=0,order=id desc,limit=10[/!show.list_auto]
如果要同时调用文章和产品,并且要排序,只能用万能标签:
SELECT id,title,1 as type FROM {dbprefix}}ecms_news UNION ALL SELECT id,title,2 FROM {dbprefix}}ecms_product ORDER BY id DESC LIMIT 10
全站搜索配置与自定义字段索引
后台的“全站搜索”只能搜主表字段,附表字段即使你填了内容也搜不到,优化方法:
- 去后台->系统设置->系统配置->搜索配置,勾选需要搜索的模型。
- 附加:自定义字段必须“启用搜索”,编辑字段时,有个“是否参与搜索”选项,务必选“是”。
- 如果搜索还是慢,因为附表字段没有索引,去数据库执行:
ALTER TABLE `{dbprefix}}ecms_product_data_1` ADD FULLTEXT INDEX `idx_content` (`content`);
注意:这是MyISAM引擎才支持全文索引,InnoDB引擎建议用LIKE '%keyword%',但大数据量下性能堪忧,更高效的做法是把需要搜索的短文本字段放到主表,比如产品的“型号”、“品牌”等。
模板中调用附表字段的实现技巧
如果不想写复杂SQL,又想在列表页快速调用附表字段,可以用帝国自带的“数据关联”功能,在模型管理->字段管理里,把附表字段设置为“关联主表”模式,这样在列表标签里,系统会自动附加查询,但注意,这会影响列表页性能,因为每条记录多一次查询。
更推荐的做法是:在模型里,把高频使用的小字段移至主表,价格”(单行文本、数字)完全可以放主表,“产品详细描述”(多行文本、编辑器)才放附表。
通过数据表分组优化,把不同频率、不同数据量的字段合理分布,比你写一百个灵动标签都管用。这是帝国CMS二次开发的根本——表结构不合理,一切模板技巧都是空中楼阁,下次再遇到前台不显示,先看字段位置,再看SQL是否漏了data_表,最后检查是否有缓存,按这个顺序排查,半小时内必然定位问题。



发表评论