版本:V5.3
文件名称:./include/dedetag.class.php
类名:DedeTagParse
源代码版权归属织梦所有,代码中加入了我的大部分注释。
/********************************************** //DedeTagParse Dede织梦模板类 function c____DedeTagParse(); ***********************************************/ class DedeTagParse { var $NameSpace = 'dede'; //标记的名字空间 var $TagStartWord = '{'; //标记起始 var $TagEndWord = '}'; //标记结束 var $TagMaxLen = 64; //标记名称的最大值 var $CharToLow = true; // true表示对属性和标记名称不区分大小写 var $IsCache = FALSE; //是否使用缓冲 var $TempMkTime = 0; var $CacheFile = ''; var $SourceString = ''; //模板字符串 var $CTags = ''; //标记集合 var $Count = -1; //$Tags标记个数 var $refObj = ''; //引用当前模板类的对象 function __construct() { if(!isset($GLOBALS['cfg_tplcache'])) { $GLOBALS['cfg_tplcache'] = 'N'; } if($GLOBALS['cfg_tplcache']=='Y') { $this->IsCache = true; } else { $this->IsCache = FALSE; } $this->NameSpace = 'dede'; $this->TagStartWord = '{'; $this->TagEndWord = '}'; $this->TagMaxLen = 64; $this->CharToLow = true; $this->SourceString = ''; $this->CTags = Array(); $this->Count = -1; $this->TempMkTime = 0; $this->CacheFile = ''; } function DedeTagParse() { $this->__construct(); } //设置标记的命名空间,默认为dede function SetNameSpace($str,$s="{",$e="}") { $this->NameSpace = strtolower($str); $this->TagStartWord = $s; $this->TagEndWord = $e; } //重置成员变量或Clear function SetDefault() { $this->SourceString = ''; $this->CTags = ''; $this->Count=-1; } function GetCount() { return $this->Count+1; } function Clear() { $this->SetDefault(); } //检测模板缓冲 function LoadCache($filename) { global $cfg_tplcache,$cfg_tplcache_dir; if(!$this->IsCache) { return false; } $cdir = dirname($filename); $cachedir = DEDEROOT.$cfg_tplcache_dir; $ckfile = str_replace($cdir,'',$filename).substr(md5($filename),0,16).'.inc'; $ckfullfile = $cachedir.'/'.$ckfile; $ckfullfile_t = $cachedir.'/'.$ckfile.'.txt'; $this->CacheFile = $ckfullfile; $this->TempMkTime = filemtime($filename); if(!file_exists($ckfullfile)||!file_exists($ckfullfile_t)) { return false; } //检测模板最后更新时间 $fp = fopen($ckfullfile_t,'r'); $time_info = trim(fgets($fp,64)); fclose($fp); if($time_info != $this->TempMkTime) { return false; } //引入缓冲数组 include($this->CacheFile); //把缓冲数组内容读入类 if(isset($z) && is_array($z)) { foreach($z as $k=>$v) { $this->Count++; $ctag = new DedeTAg(); $ctag->CAttribute = new DedeAttribute(); $ctag->IsReplace = FALSE; $ctag->TagName = $v[0]; $ctag->InnerText = $v[1]; $ctag->StartPos = $v[2]; $ctag->EndPos = $v[3]; $ctag->TagValue = ''; $ctag->TagID = $k; if(isset($v[4]) && is_array($v[4])) { $i = 0; foreach($v[4] as $k=>$v) { $ctag->CAttribute->Count++; $ctag->CAttribute->Items[$k]=$v; } } $this->CTags[$this->Count] = $ctag; } } else { //模板没有缓冲数组 $this->CTags = ''; $this->Count = -1; } return true; } //写入缓冲 function SaveCache() { $fp = fopen($this->CacheFile.'.txt',"w"); fwrite($fp,$this->TempMkTime."/n"); fclose($fp); $fp = fopen($this->CacheFile,"w"); flock($fp,3); fwrite($fp,'<'.'?php'."/r/n"); if(is_array($this->CTags)) { foreach($this->CTags as $tid=>$ctag) { $arrayValue = 'Array("'.$ctag->TagName.'",'; $arrayValue .= '"'.str_replace('$','/$',str_replace("/r","//r",str_replace("/n","//n",str_replace('"','/"',str_replace("//","////",$ctag->InnerText))))).'"'; $arrayValue .= ",{$ctag->StartPos},{$ctag->EndPos});"; fwrite($fp,"/$z[$tid]={$arrayValue}/n"); if(is_array($ctag->CAttribute->Items)) { foreach($ctag->CAttribute->Items as $k=>$v) { $v = str_replace("//","////",$v); $v = str_replace('"',"//".'"',$v); $v = str_replace('$','/$',$v); $k = trim(str_replace("'","",$k)); if($k=="") { continue; } if($k!='tagname') { fwrite($fp,"/$z[$tid][4]['$k']=/"$v/";/n"); } } } } } fwrite($fp,"/n".'?'.'>'); fclose($fp); } //载入模板文件 function LoadTemplate($filename) { $this->SetDefault(); //重置成员变量或Clear //打开模板文件进行读取 $fp = @fopen($filename,"r") or die(" Template Not Found! ".$filename."
"); while($line = fgets($fp,1024)) { /* * 赋值运算将原变量的值拷贝到新变量中(传值赋值),所以改变其中一个并不影响另一个。 * 这也适合于在很密集的循环中拷贝一些值例如大数组。也可以使用引用赋值,用 $var = &$othervar; 语法。 * 引用赋值意味着两个变量都指向同一个数据,没有任何数据的拷贝。 * * .= 相当于 += */ $this->SourceString .= $line; } fclose($fp); //关闭文件 //如果模板缓冲文件存在返回null,否则进行模板文件解析 if($this->LoadCache($filename)) { return ''; } else { $this->ParseTemplet(); //解析模板 } } function LoadTemplet($filename) { $this->LoadTemplate($filename); } function LoadFile($filename) { $this->LoadTemplate($filename); } //载入模板字符串 function LoadSource($str) { $this->SetDefault(); $this->SourceString = $str; $this->IsCache = FALSE; $this->ParseTemplet(); } function LoadString($str) { $this->LoadSource($str); } //获得指定名称的Tag的ID(如果有多个同名的Tag,则取没有被取代为内容的第一个Tag) function GetTagID($str) { if($this->Count==-1) { return -1; } if($this->CharToLow) { $str=strtolower($str); } foreach($this->CTags as $id=>$CTag) { if($CTag->TagName==$str && !$CTag->IsReplace) { return $id; break; } } return -1; } //获得指定名称的CTag数据类(如果有多个同名的Tag,则取没有被分配内容的第一个Tag) function GetTag($str) { if($this->Count==-1) { return ''; } if($this->CharToLow) { $str=strtolower($str); } foreach($this->CTags as $id=>$CTag) { if($CTag->TagName==$str && !$CTag->IsReplace) { return $CTag; break; } } return ''; } function GetTagByName($str) { return $this->GetTag($str); } //获得指定ID的CTag数据类 function GetTagByID($id) { if(isset($this->CTags[$id])) { return $this->CTags[$id]; } else { return ''; } } //给_vars数组传递一个元素 function AssignVar($vname,$vvalue) { if(!isset($_sys_globals['define'])) { $_sys_globals['define'] = 'yes'; } $_sys_globals[$vname] = $vvalue; } //分配指定ID的标记的值 function Assign($i,$str,$runfunc = true) { if(isset($this->CTags[$i])) { $this->CTags[$i]->IsReplace = true; $this->CTags[$i]->TagValue = $str; if( $this->CTags[$i]->GetAtt('function')!='' && $runfunc ) { $this->CTags[$i]->TagValue = $this->EvalFunc( $str, $this->CTags[$i]->GetAtt('function'),$this->CTags[$i] ); } } } //分配指定名称的标记的值,如果标记包含属性,请不要用此函数 function AssignName($tagname,$str) { foreach($this->CTags as $id=>$CTag) { if($CTag->TagName==$tagname) { $this->Assign($id,$str); } } } //处理特殊标记 function AssignSysTag() { global $_sys_globals; for($i=0;$i<=$this->Count;$i++) { $CTag = $this->CTags[$i]; $str = ''; //获取一个外部变量 if( $CTag->TagName == 'global' ) { $str = $this->GetGlobals($CTag->GetAtt('name')); if( $this->CTags[$i]->GetAtt('function')!='' ) { $str = $this->EvalFunc( $this->CTags[$i]->TagValue, $this->CTags[$i]->GetAtt('function'),$this->CTags[$i] ); } $this->CTags[$i]->IsReplace = true; $this->CTags[$i]->TagValue = $str; } //引入静态文件 else if( $CTag->TagName == 'include' ) { $filename = ($CTag->GetAtt('file')=='' ? $CTag->GetAtt('filename') : $CTag->GetAtt('file') ); $str = $this->IncludeFile($filename,$CTag->GetAtt('ismake')); $this->CTags[$i]->IsReplace = true; $this->CTags[$i]->TagValue = $str; } //循环一个普通数组 else if( $CTag->TagName == 'foreach' ) { $arr = $this->CTags[$i]->GetAtt('array'); if(isset($GLOBALS[$arr])) { foreach($GLOBALS[$arr] as $k=>$v) { $istr = ''; $istr .= preg_replace("//[field:key([/r/n/t/f ]+)///]/is",$k,$this->CTags[$i]->InnerText); $str .= preg_replace("//[field:value([/r/n/t/f ]+)///]/is",$v,$istr); } } $this->CTags[$i]->IsReplace = true; $this->CTags[$i]->TagValue = $str; } //设置/获取变量值 else if( $CTag->TagName == 'var' ) { $vname = $this->CTags[$i]->GetAtt('name'); if($vname=='') { $str = ''; } else if($this->CTags[$i]->GetAtt('value')!='') { $_vars[$vname] = $this->CTags[$i]->GetAtt('value'); } else { $str = (isset($_vars[$vname]) ? $_vars[$vname] : ''); } $this->CTags[$i]->IsReplace = true; $this->CTags[$i]->TagValue = $str; } //运行PHP接口 if( $CTag->GetAtt('runphp') == 'yes' ) { $this->RunPHP($CTag,$i); } if(is_array($this->CTags[$i]->TagValue)) { $this->CTags[$i]->TagValue = 'array'; } } } //运行PHP代码 function RunPHP(&$refObj,$i) { $DedeMeValue = $phpcode = ''; if($refObj->GetAtt('source')=='value') { $phpcode = $this->CTags[$i]->TagValue; } else { $DedeMeValue = $this->CTags[$i]->TagValue; $phpcode = $refObj->GetInnerText(); } $phpcode = eregi_replace("'@me'|/"@me/"|@me",'$DedeMeValue',$phpcode); @eval($phpcode); //or die("