帝国CMS列表页模板使用程序代码(docode)$r有哪些字段

作者:凡帝网 分类:帝国CMS教程 发布时间:2026-07-28 浏览量:0

涉及文件

分析文件:eadmin/admin/template/AddListtemp.php
核心函数:ReplaceListVars()e/class/connect.php
渲染入口:ListHtml() / ListHtmlIndex()e/class/functions.php
最重要的$r对象的字段就是主表字段
docode("使用程序代码")勾选后,列表内容模板 list.var 不再被当作纯字符串替换,而是先作为 PHP 代码 eval() 执行,执行完再继续做标准的 [!--字段--] 占位符替换。整条链路如下。

1. 数据流:勾选框 → 数据库 → 渲染

表单层

AddListtemp.php:188 中的勾选框:

<input name="docode" type="checkbox" id="docode" value="1"<?=$r['docode']==1?' checked':''?>>
<a title="list.var使用程序代码">使用程序代码</a>

入库层

ListListtemp.php:40-42 把勾选值强转成 0/1,写入 enewslisttemp.docode 字段(修改时同理在 ListListtemp.php:80-82):

$docode=(int)$add['docode'];
$sql=$empire->updatesql("insert into ...enewslisttemp(...,docode) values(...,'$docode')","ins");

读取层

渲染前从模板表查询时把 docode 一并取出,例如:

  • 动态列表页 e/action/ListInfo/index.php:257
  • 静态生成 e/class/functions.php:2406

2. 核心实现:eval() 前置执行

ReplaceListVars() 是每条信息行都会调用的"列表变量替换"函数。签名见 connect.php:4787

function ReplaceListVars($no,$listtemp,$subnews,$subtitle,$formatdate,$url,$haveclass,$r,$field,$docode=0){
    global $empire,$public_r,$class_r,$class_zr,$fun_r,$dbtbpre,$emod_r,$class_tr,$level_r,$navclassid,$etable_r,$etable_t;
    ...
    if($docode==1)
    {
        $listtemp=stripSlashes($listtemp);
        eval($listtemp);        // ← 关键:list.var 作为 PHP 执行
    }
    $ylisttemp=$listtemp;
    ...
    // 之后才是常规 str_replace('[!--字段--]', ...)

调用方在 functions.php:3360 与 functions.php:3423ListHtml 静态生成)和 functions.php:3653ListHtmlIndex)把 $docode 透传进去:

$docode=$listtemp_r['docode'];
...
$repvar=ReplaceListVars($no,$listvar,$subnews,$subtitle,$formatdate,$url,$haveclass,$k,$field,$docode);

3. docode 勾选后"支持的变量" = eval 作用域内可见的变量

因为 eval() 在 ReplaceListVars() 函数局部作用域内执行,所以模板里能直接访问的变量就是该函数的局部变量与 global 声明。这正是 docode 模式下用户写 PHP 时能拿到的全部"变量":

变量 含义 来源
$r 当前这条信息的整行数据库记录(id/title/classid/userid/onclick/newstime/titlepic…含模型自定义字段) 函数参数 $k(fetch 出的行)
$no 信息编号(行序号) 函数参数
$listtemp list.var 模板字符串本身——用户代码应修改它来输出最终内容 函数参数
$field ['mid']['fr'](字段名数组)、['fcount'] ReturnReplaceListF()
$add 栏目名(带链接 HTML,由 sys_ReturnBqClassname 生成) 函数内计算
$subnews/$subtitle/$formatdate/$url/$haveclass 截取字数、时间格式、URL、是否有栏目 函数参数
$empire $public_r $class_r $class_zr $class_tr $emod_r $level_r $navclassid $dbtbpre $fun_r $etable_r $etable_t 全局 CMS 上下文 global 声明

其中最关键的是 $r(当前信息记录)和 $listtemp(待输出模板)。常见写法是:

<?php
// list.var 内容示例(docode 模式)
if($r['onclick']>100){
    $listtemp='<li class="hot">[!--title--] ([!--onclick--])</li>';
}else{
    $listtemp='<li>[!--title--]</li>';
}
?>

4. docode 与普通变量替换是"叠加"关系,不是"二选一"

这是最容易被误解的点。看 connect.php:4797-4860 的执行顺序:

  1.  eval($listtemp) — 用户 PHP 跑完,$listtemp 可能已被改成新字符串

  2.  用 for 循环对 $emod_r[$mid]['listtempf'] 里列出的每个字段做 $listtemp=str_replace('[!--'.$f.'--]',$value,$listtemp)connect.php:4860

  3.  替换一组固定占位符:

    • [!--id--]
    • [!--classid--]
    • [!--class.name--]
    • [!--ttid--]
    • [!--tt.name--]
    • [!--tt.url--]
    • [!--userfen--]
    • [!--titleurl--]
    • [!--no.num--]
    • [!--plnum--]
    • [!--userid--]
    • [!--username--]
    • [!--onclick--]
    • [!--oldtitle--]
    • [!--totaldown--]
    • [!--this.classlink--]
    • [!--this.classname--]

    connect.php:4863-4886

所以即便勾选了 docode,AddListtemp.php 第 289-344 行"(2)、列表内容模板(list.var)支持的变量"里列出的全部 [!--xxx--] 占位符仍然有效——它们是在 eval 之后由系统继续替换的。docode 只是让你能在替换之前用 PHP 动态决定模板长什么样、做条件分支/循环/字段计算。

5. 安全开关 candocode

模板保存时调用 RepPhpAspJspcode() 对 listvar 做过滤(ListListtemp.php:31)。看 functions.php:335-349

function RepPhpAspJspcode($string){
    global $public_r;
    if(!$public_r['candocode']){          // ← 系统设置开关
        $string=str_replace("<?","&lt;?",$string);
        $string=str_replace("<%","&lt;%",$string);
        ...
    }
    return $string;
}
  • 系统参数 candocode 关闭时,<? <% <script> 会被转义,即使勾了 docode,PHP 代码也无法在 eval 里正常执行(被当字符串了)。
  • 只有后台开启"允许模板使用代码"($public_r['candocode']),docode 的 eval 才真正能跑用户写的 PHP。这是 docode 的总闸。

小结

docode 的实现本质就是在 ReplaceListVars() 里对 list.var 内容做一次 eval(),且发生在常规 str_replace('[!--字段--]',…) 之前。所谓"docode 模式下支持的变量",并不是一份新变量表,而是 eval 作用域暴露给用户 PHP 的函数局部变量($r/$listtemp/$no/$field/$add 及一批 global);执行完后,原 AddListtemp.php 列出的所有 [!--xxx--] 占位符仍按原机制继续替换。安全上由 $public_r['candocode'] 总闸与保存时的 RepPhpAspJspcode 共同控制——这是一个允许后台管理员在模板里写 PHP 的能力,需谨慎开放。

 

关键代码位置索引

文件 行号 作用
eadmin/admin/template/AddListtemp.php 188 docode 勾选框 UI
eadmin/admin/template/AddListtemp.php 289-344 list.var 支持的变量说明
eadmin/admin/template/ListListtemp.php 40-42 新增模板时写入 docode
eadmin/admin/template/ListListtemp.php 80-82 修改模板时更新 docode
e/class/connect.php 4787 ReplaceListVars() 函数签名
e/class/connect.php 4797-4801 eval($listtemp) 核心执行
e/class/connect.php 4860 模型字段占位符替换
e/class/connect.php 4863-4886 固定占位符替换
e/class/functions.php 335-349 RepPhpAspJspcode() 安全过滤
e/class/functions.php 2406 静态生成时查询 docode
e/class/functions.php 3360, 3423 ListHtml() 透传 docode
e/class/functions.php 3653, 3727 ListHtmlIndex() 透传 docode
e/action/ListInfo/index.php 257 动态列表页查询 docode

微信扫码咨询

微信二维码