一个深夜的紧急工单
凌晨两点,客户打来电话:“后台自定义模型建好了,字段也加了,前台列表页死活不显示数据,SQL调试模式也开了,但就是一片空白。” 我揉了揉眼睛,打开帝国CMS后台,进入“系统设置 → 数据表管理”,找到那个自定义模型对应的数据表,发现字段虽然存在,但主表索引和附表索引完全不匹配,更麻烦的是,客户之前用phpMyAdmin手动删除过几个索引,导致帝国CMS的“重建索引”功能直接报错。
排查步骤:
帝国CMS二次开发实战,从数据表字段索引删除到全站搜索优化
- 检查数据表结构:进入
phome_ecms_开头的自定义表,对比主表(phome_ecms_模型名)和附表(phome_ecms_模型名_data_)的索引是否一致。 - 删除冗余索引:如果发现索引冲突,用SQL直接删除:
ALTER TABLE phome_ecms_custom DROP INDEX index_name;
- 重建帝国CMS索引:在后台“数据表管理”中,点“更新数据表缓存”和“重建索引”,确保系统自检通过。
灵动标签SQL调用:从入门到放弃?
很多新手卡在灵动标签的[e:loop]写法上,其实核心就一句话:灵动标签是“查询模板”,不是“循环标签”,它的SQL是直接查主表,且不自动关联附表。
典型错误:
[e:loop={"select * from phome_ecms_custom where id='1'",1,24,0}]
这样写查不到附表字段,因为只包含主表字段。
正确写法(联动附表):
[e:loop={"select a.*, b.custom_field from phome_ecms_custom a left join phome_ecms_custom_data_ b on a.id=b.id where a.id='1'",1,24,0}]
<?php echo $bqr[custom_field];?>
[/e:loop]
注意:灵动标签的$bqr是当前记录数组,$bqno是序号,附表字段必须通过JOIN获取,否则永远为NULL。
列表模板和内容模板的变量调用陷阱
在列表模板(list.htm)中,帝国CMS默认只加载主表字段,如果你想调用附表的content字段,必须用$r[content]?错!那是内容模板的写法。
列表模板正确调用附表字段:
<?php
// 在list模板中,需要手动查询附表
$data_r = $empire->fetch1("select * from phome_ecms_custom_data_ where id='$r[id]'");
echo $data_r['content'];
?>
或者更高效:在系统模型的“列表模板”字段绑定里,勾选“显示附表字段”,但这样会增加数据库压力。
模板(show.htm)则简单得多:**
<?=$navinfor['custom_field']?>
```页是`$navinfor`完整数组,包含了主表和附表合并后的数据。
## 万能标签VS智能标签:到底用谁?
**万能标签(`[e:universal]`)**:自由度最高,自己写SQL,适合复杂统计,但效率低,每次查询都实时执行。
**智能标签(`[e:smart]`)**:基于模型定义,自动处理主附表关联,支持缓存,适合列表展示。
**使用场景抉择:**
- 如果你要展示“最新3条评论+最新5条文章”这种混合SQL,用万能标签:
```html
[e:universal={"select * from phome_ecms_news order by newstime desc limit 5",0,5,0}]
- 如果你是单纯调同一模型的数据,且需要附表字段,用智能标签:
[e:smart={model=1,ttid=0,line=10,type=0,order=id desc,table=news}]注意:智能标签的
table参数必须是模型名,它会自动JOIN附表,但有个坑——它不会自动缓存,需要手动开启“标签缓存”。
全站搜索配置:自定义字段的索引噩梦
客户要求搜索自定义字段,后台“系统设置 → 搜索设置”里勾选了字段,但前端搜索无结果,原因往往是:该字段没有加入全文索引。
正确做法:
- 在数据表管理中,给自定义字段添加
FULLTEXT索引:ALTER TABLE phome_ecms_custom_data_ ADD FULLTEXT(custom_field);
- 修改搜索模板,指定搜索附表字段:
<form action="/search/" method="get"> <input type="hidden" name="searchtype" value="custom"> <input type="hidden" name="tbname" value="custom"> <input type="text" name="keyboard" placeholder="搜索自定义字段"> </form>
- 后台搜索参数里,将“搜索字段”设置为
custom_field,并勾选“模糊查询”。特别注意: 帝国CMS默认只搜索主表title和keyboard,你需要修改/e/search/index.php中的SQL拼接逻辑:
// 在index.php中增加自定义字段搜索
if($searchtype=='custom') {
$where = " where custom_field like '%$keyboard%' ";
}
模板中调用附表字段的实现技巧(终极方案)
对于复杂模板,不想写SQL,可以用帝国CMS内置的getTable函数:
<?php
// 获取附表数据
$add_data = $empire->fetch1("select * from phome_ecms_".$r['tbname']."_data_ where id='".$r['id']."'");
// 然后直接输出
echo $add_data['my_field'];
?>
但更有优雅的写法:利用sys_ReturnAddField函数(仅限内容页):
<?=sys_ReturnAddField($navinfor, 'my_field')?>
这个函数会自动判断当前数据是否包含附表字段,如果包含直接返回,不包含会额外查询一次。
性能优化建议: 如果列表页要显示5个附表字段,不要写5次fetch1,而是合并成一次查询:
<?php
$fields = 'field1,field2,field3';
$add_data = $empire->fetch1("select $fields from phome_ecms_custom_data_ where id='$r[id]'");
?>
回到最初的问题,客户的索引删除后,我不仅重建了索引,还发现他自定义模型的“主表字段”和“附表字段”命名冲突——主表有个title,附表也有个title,导致搜索时字段覆盖,我修改了附表字段名为content_title,前台立即恢复显示,帝国CMS的索引管理看似简单,但真正涉及多表关联时,多一分细心,少一分半夜的骚扰电话。



发表评论