作为常年与帝国CMS打交道的二开老手,今天必须把生产环境里最磨人的“数据表同步数据丢失”问题掰开揉碎讲清楚,你可能会遇到这种情况:明明后台更新了信息,数据库里主表有记录,但自定义模型创建的附表数据却像蒸发了一样,导致前台列表页直接空白,别急着摔键盘,咱们一步步拆解。
自定义模型创建后前台不显示的排查思路
突然发现新建的字段在前台模板里输出为空白,别先怀疑模板标签写错了。第一刀砍向后台“系统设置-数据表管理-管理系统模型”,检查该模型是否勾选了“前台显示”,曾经有个项目因为迁移服务器重装了帝国,新恢复的模型默认没勾选此项,浪费了三天时间。
帝国CMS数据表同步数据丢失的深层排查与实战技巧
如果确认显示开启,第二步进入“数据表管理”找到该模型对应的附件表(通常是phome_enewsb_模型ID),用phpMyAdmin执行:
SHOW COLUMNS FROM `phome_enewsb_2` WHERE Field = 'myfield';
若字段存在但前台不输出,大概率是模板里[!--myfield--]标签与字段名大小写不匹配——帝国对字段大小写极其敏感,myfield和MyField是两码事。
灵动标签SQL调用:从基础到进阶
灵动标签是帝国CMS的灵魂,但很多人连最基本的[e:loop]都写出过bug,比如要调用某个自定义模型下status=1且create_time在最近7天的数据,新手往往会写:
[e:loop={"select * from phome_ecms_article where status=1 limit 10",10,24,0}]
这里有个致命伤:默认的新闻模型主表phome_ecms_article并不包含自定义字段,需要用phome_ecms_article_data_1(软文模型附表),正确写法是:
[e:loop={"select a.*,b.myfield from phome_ecms_article a left join phome_ecms_article_data_1 b on a.id=b.id where a.status=1 and a.newstime>unix_timestamp()-604800 order by a.newstime desc limit 0,10",10,24,0}]
注意:这里的left join必须带上主附表的关联条件,否则数据同步丢失后会产生笛卡尔积,直接刷爆内存。
列表模板与内容模板的变量调用陷阱
列表页经常需要调用字段总和,比如某个自定义数字字段price,在列表模板中直接写[!--price--]输出的是单条记录值,如果要计算总和,必须使用灵动标签的$GLOBALS[‘navinfor’]:
<?php
$total = 0;
$sql = $empire->query("select price from phome_ecms_article_data_1 where id in (select id from phome_ecms_article where classid=48)");
while($r = $empire->fetch($sql)){
$total += $r['price'];
}
echo $total;
?>
模板中调用附表字段时要注意:帝国默认只加载主表字段,需要在模板头部添加:
<?php
$addsql=$empire->query("select * from phome_ecms_article_data_".$r[stb]." where id='$navinfor[id]'");
$addval=$empire->fetch($addsql);
$navinfor['mytext']=$addval['mytext'];
?>
这样前端模板直接用[!--mytext--]就能输出,而且能避免数据同步后字段缺失报错。
万能标签与智能标签:何时选谁最合适
万能标签[showclas]适合做固定模块如“公司简介”“联系我们”,因为它直接绑定栏目ID,不依赖系统ID,但做产品列表时,用智能标签[phomenews]更灵活:
[phomenews]'栏目ID','显示条数','标题截取','是否显示时间','操作类型'[/phomenews]
比如要调用所有推荐产品(自定义字段recommend=1),万能标签会捉襟见肘,智能标签配合SQL:
[phomenews]'0,48','10','0','0','24','1',0,'',0,'','','','','',0,'','',0,'','','','','','','',0,'','','','','','','','','','','','','','','','','',1[/phomenews]
注意第27个参数设置1代表开启自定义字段查询,这样在模板里才能用[!--recommend--]输出。
全站搜索配置与自定义字段索引
数据同步丢失后最怕搜不到内容,进入后台“系统设置-全站搜索-搜索数据表”,确保自定义模型对应的数据表已添加,关键步骤在“系统设置-数据表管理-对应模型-搜索字段”,必须把需要搜索的字段勾选上。
如果字段类型为text或mediumtext,记得要建立全文索引:
ALTER TABLE `phome_ecms_article_data_1` ADD FULLTEXT INDEX `ft_mytext` (`mytext`);
否则搜索时会变成全表扫描,数据量大时直接超时,帝国搜索默认只匹配主表字段,附表字段需要在e/search/result/index.php里加上:
$searchsql.=" left join {$dbtbpre}ecms_article_data_".$class_r[$search_r['classid']]['tid']." b on a.id=b.id";
否则自定义字段永远搜不到。
模板中调用附表字段的实现技巧
终极方案是写一个自定义函数,在e/class/userfun.php里加上:
function get_addfield($id,$field,$tbname='article'){
global $empire,$dbtbpre;
$stb = $empire->fetch1("select stb from {$dbtbpre}ecms_".$tbname." where id='$id'");
$val = $empire->fetch1("select $field from {$dbtbpre}ecms_".$tbname."_data_".$stb['stb']." where id='$id'");
return $val[$field];
}
模板里调用:<?=get_addfield($navinfor[id],'myfield','article')?>
这样即使是刚同步完数据,也能保证字段正常输出,最后一个忠告:生产环境做数据表同步前,务必用mysqldump备份附表和主表的id对照关系,否则一旦丢失,只能通过classid和时间戳找回数据。



发表评论