TagName); } /** * 获取值 * * @access public * @return string */ function GetValue() { return $this->TagValue; } //下面两个成员函数仅是为了兼容旧版 function GetTagName() { return strtolower($this->TagName); } function GetTagValue() { return $this->TagValue; } //获取标记的指定属性 function IsAttribute($str) { return $this->CAttribute->IsAttribute($str); } function GetAttribute($str) { return $this->CAttribute->GetAtt($str); } function GetAtt($str) { return $this->CAttribute->GetAtt($str); } function GetInnerText() { return $this->InnerText; } } /** * DedeTagParse Dede织梦模板类 * function c____DedeTagParse(); * * @package DedeTagParse * @subpackage DedeCMS.Libraries * @link http://www.dedecms.com */ 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 = array(); //标记集合 var $Count = -1; //$Tags标记个数 var $refObj = ''; //引用当前模板类的对象 var $taghashfile = ''; function __construct() { if(!isset($GLOBALS['cfg_tplcache'])) { $GLOBALS['cfg_tplcache'] = 'N'; } if($GLOBALS['cfg_tplcache']=='Y') { $this->IsCache = TRUE; } else { $this->IsCache = FALSE; } if ( DEDE_ENVIRONMENT == 'development' ) { $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 * * @access public * @param string $str 字符串 * @param string $s 开始标记 * @param string $e 结束标记 * @return void */ function SetNameSpace($str, $s="{", $e="}") { $this->NameSpace = strtolower($str); $this->TagStartWord = $s; $this->TagEndWord = $e; } /** * 重置成员变量或Clear * * @access public * @return void */ function SetDefault() { $this->SourceString = ''; $this->CTags = array(); $this->Count=-1; } /** * 强制引用 * * @access public * @param object $refObj 隶属对象 * @return void */ function SetRefObj(&$refObj) { $this->refObj = $refObj; } function GetCount() { return $this->Count+1; } function Clear() { $this->SetDefault(); } // ------------------------------------------------------------------------ /** * CheckDisabledFunctions * * COMMENT : CheckDisabledFunctions : 检查是否存在禁止的函数 * * @access public * @param string * @return bool */ function CheckDisabledFunctions($str,&$errmsg='') { global $cfg_disable_funs; $cfg_disable_funs = isset($cfg_disable_funs)? $cfg_disable_funs : 'phpinfo,eval,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents,fsockopen,fopen,fwrite'; // 模板引擎增加disable_functions if (defined('DEDEDISFUN')) { $tokens = token_get_all_nl('"); $disabled_functions = explode(',', $cfg_disable_funs); foreach ($tokens as $token) { if (is_array($token)) { if ($token[0] = '306' && in_array($token[1], $disabled_functions)) { $errmsg = 'DedeCMS Error:function disabled "'.$token[1].'" more...'; return FALSE; } } } } return TRUE; } /** * 检测模板缓存 * * @access public * @param string $filename 文件名称 * @return string */ 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); $errmsg = ''; //把缓冲数组内容读入类 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; $ctag->CAttribute->Items = array(); 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; } /** * 写入缓存 * * @access public * @param string * @return string */ 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"); $errmsg = ''; if(is_array($this->CTags)) { foreach($this->CTags as $tid=>$ctag) { $arrayValue = 'Array("'.$ctag->TagName.'",'; if (!$this->CheckDisabledFunctions($ctag->InnerText, $errmsg)) { fclose($fp); @unlink($this->taghashfile); @unlink($this->CacheFile); @unlink($this->CacheFile.'.txt'); die($errmsg); } $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)) { fwrite($fp,"\$z[$tid][4]=array();\n"); 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); } /** * 载入模板文件 * * @access public * @param string $filename 文件名称 * @return string */ function LoadTemplate($filename) { $this->SetDefault(); if(!file_exists($filename)) { $this->SourceString = " $filename Not Found! "; $this->ParseTemplet(); } else { $fp = @fopen($filename, "r"); while($line = fgets($fp,1024)) { $this->SourceString .= $line; } fclose($fp); if($this->LoadCache($filename)) { return ''; } else { $this->ParseTemplet(); } } } // 仅用于兼容旧版本 function LoadTemplet($filename) { $this->LoadTemplate($filename); } // 仅用于兼容旧版本 function LoadFile($filename) { $this->LoadTemplate($filename); } /** * 载入模板字符串 * * @access public * @param string $str 字符串 * @return void */ function LoadSource($str) { /* $this->SetDefault(); $this->SourceString = $str; $this->IsCache = FALSE; $this->ParseTemplet(); */ //优化模板字符串存取读取方式 $this->taghashfile = $filename = DEDEDATA.'/tplcache/'.md5($str).'.inc'; if( !is_file($filename) ) { file_put_contents($filename, $str); } $this->LoadTemplate($filename); } function LoadString($str) { $this->LoadSource($str); } /** * 获得指定名称的Tag的ID(如果有多个同名的Tag,则取没有被取代为内容的第一个Tag) * * @access public * @param string $str 字符串 * @return int */ 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) * * @access public * @param string $str 字符串 * @return string */ 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 ''; } /** * 通过名称获取标记 * * @access public * @param string $str 字符串 * @return string */ function GetTagByName($str) { return $this->GetTag($str); } /** * 获得指定ID的CTag数据类 * * @access public * @param string 标签id * @return string */ function GetTagByID($id) { if(isset($this->CTags[$id])) { return $this->CTags[$id]; } else { return ''; } } /** * 给_vars数组传递一个元素 * * @access public * @param string $vname 标签名 * @param string $vvalue 标签值 * @return string */ function AssignVar($vname, $vvalue) { if(!isset($_sys_globals['define'])) { $_sys_globals['define'] = 'yes'; } $_sys_globals[$vname] = $vvalue; } /** * 分配指定ID的标记的值 * * @access public * @param string $i 标签id * @param string $str 字符串 * @param string $runfunc 运行函数 * @return void */ 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] ); } } } /** * 分配指定名称的标记的值,如果标记包含属性,请不要用此函数 * * @access public * @param string $tagname 标签名称 * @param string $str 字符串 * @return void */ function AssignName($tagname, $str) { foreach($this->CTags as $id=>$CTag) { if($CTag->TagName==$tagname) { $this->Assign($id,$str); } } } /** * 处理特殊标记 * * @access public * @return void */ 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] ); $str = $this->EvalFunc( $str, $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 = preg_replace("/'@me'|\"@me\"|@me/i", '$DedeMeValue', $phpcode); @eval($phpcode); //or die("$phpcode"); $this->CTags[$i]->TagValue = $DedeMeValue; $this->CTags[$i]->IsReplace = TRUE; } /** * 把分析模板输出到一个字符串中 * 不替换没被处理的值 * * @access public * @return string */ function GetResultNP() { $ResultString = ''; if($this->Count==-1) { return $this->SourceString; } $this->AssignSysTag(); $nextTagEnd = 0; $strok = ""; for($i=0;$i<=$this->Count;$i++) { if($this->CTags[$i]->GetValue()!="") { if($this->CTags[$i]->GetValue()=='#@Delete@#') { $this->CTags[$i]->TagValue = ""; } $ResultString .= substr($this->SourceString,$nextTagEnd,$this->CTags[$i]->StartPos-$nextTagEnd); $ResultString .= $this->CTags[$i]->GetValue(); $nextTagEnd = $this->CTags[$i]->EndPos; } } $slen = strlen($this->SourceString); if($slen>$nextTagEnd) { $ResultString .= substr($this->SourceString,$nextTagEnd,$slen-$nextTagEnd); } return $ResultString; } /** * 把分析模板输出到一个字符串中,并返回 * * @access public * @return string */ function GetResult() { $ResultString = ''; if($this->Count==-1) { return $this->SourceString; } $this->AssignSysTag(); $nextTagEnd = 0; $strok = ""; for($i=0;$i<=$this->Count;$i++) { $ResultString .= substr($this->SourceString,$nextTagEnd,$this->CTags[$i]->StartPos-$nextTagEnd); $ResultString .= $this->CTags[$i]->GetValue(); $nextTagEnd = $this->CTags[$i]->EndPos; } $slen = strlen($this->SourceString); if($slen>$nextTagEnd) { $ResultString .= substr($this->SourceString,$nextTagEnd,$slen-$nextTagEnd); } return $ResultString; } /** * 直接输出解析模板 * * @access public * @return void */ function Display() { echo $this->GetResult(); } /** * 把解析模板输出为文件 * * @access public * @param string $filename 要保存到的文件 * @return string */ function SaveTo($filename) { $fp = @fopen($filename,"w") or die("DedeTag Engine Create File False"); fwrite($fp,$this->GetResult()); fclose($fp); } /** * 解析模板 * * @access public * @return string */ function ParseTemplet() { $TagStartWord = $this->TagStartWord; $TagEndWord = $this->TagEndWord; $sPos = 0; $ePos = 0; $FullTagStartWord = $TagStartWord.$this->NameSpace.":"; $sTagEndWord = $TagStartWord."/".$this->NameSpace.":"; $eTagEndWord = "/".$TagEndWord; $tsLen = strlen($FullTagStartWord); $sourceLen=strlen($this->SourceString); if( $sourceLen <= ($tsLen + 3) ) { return; } $cAtt = new DedeAttributeParse(); $cAtt->charToLow = $this->CharToLow; //遍历模板字符串,请取标记及其属性信息 for($i=0; $i < $sourceLen; $i++) { $tTagName = ''; //如果不进行此判断,将无法识别相连的两个标记 if($i-1 >= 0) { $ss = $i-1; } else { $ss = 0; } $sPos = strpos($this->SourceString,$FullTagStartWord,$ss); $isTag = $sPos; if($i==0) { $headerTag = substr($this->SourceString,0,strlen($FullTagStartWord)); if($headerTag==$FullTagStartWord) { $isTag=TRUE; $sPos=0; } } if($isTag===FALSE) { break; } //判断是否已经到倒数第三个字符(可能性几率极小,取消此逻辑) /* if($sPos > ($sourceLen-$tsLen-3) ) { break; } */ for($j=($sPos+$tsLen);$j<($sPos+$tsLen+$this->TagMaxLen);$j++) { if($j>($sourceLen-1)) { break; } else if( preg_match("/[\/ \t\r\n]/", $this->SourceString[$j]) || $this->SourceString[$j] == $this->TagEndWord ) { break; } else { $tTagName .= $this->SourceString[$j]; } } if($tTagName!='') { $i = $sPos+$tsLen; $endPos = -1; $fullTagEndWordThis = $sTagEndWord.$tTagName.$TagEndWord; $e1 = strpos($this->SourceString,$eTagEndWord, $i); $e2 = strpos($this->SourceString,$FullTagStartWord, $i); $e3 = strpos($this->SourceString,$fullTagEndWordThis,$i); //$eTagEndWord = /} $FullTagStartWord = {tag: $fullTagEndWordThis = {/tag:xxx] $e1 = trim($e1); $e2 = trim($e2); $e3 = trim($e3); $e1 = ($e1=='' ? '-1' : $e1); $e2 = ($e2=='' ? '-1' : $e2); $e3 = ($e3=='' ? '-1' : $e3); //not found '{/tag:' if($e3==-1) { $endPos = $e1; $elen = $endPos + strlen($eTagEndWord); } //not found '/}' else if($e1==-1) { $endPos = $e3; $elen = $endPos + strlen($fullTagEndWordThis); } //found '/}' and found '{/dede:' else { //if '/}' more near '{dede:'、'{/dede:' , end tag is '/}', else is '{/dede:' if($e1 < $e2 && $e1 < $e3 ) { $endPos = $e1; $elen = $endPos + strlen($eTagEndWord); } else { $endPos = $e3; $elen = $endPos + strlen($fullTagEndWordThis); } } //not found end tag , error if($endPos==-1) { echo "Tag Character postion $sPos, '$tTagName' Error!
\r\n"; break; } $i = $elen; $ePos = $endPos; //分析所找到的标记位置等信息 $attStr = ''; $innerText = ''; $startInner = 0; for($j=($sPos+$tsLen);$j < $ePos;$j++) { if($startInner==0 && ($this->SourceString[$j]==$TagEndWord && $this->SourceString[$j-1]!="\\") ) { $startInner=1; continue; } if($startInner==0) { $attStr .= $this->SourceString[$j]; } else { $innerText .= $this->SourceString[$j]; } } //echo "$attStr\r\n"; $cAtt->SetSource($attStr); if($cAtt->cAttributes->GetTagName()!='') { $this->Count++; $CDTag = new DedeTag(); $CDTag->TagName = $cAtt->cAttributes->GetTagName(); $CDTag->StartPos = $sPos; $CDTag->EndPos = $i; $CDTag->CAttribute = $cAtt->cAttributes; $CDTag->IsReplace = FALSE; $CDTag->TagID = $this->Count; $CDTag->InnerText = $innerText; $this->CTags[$this->Count] = $CDTag; } } else { $i = $sPos+$tsLen; break; } }//结束遍历模板字符串 if($this->IsCache) { $this->SaveCache(); } } /** * 处理某字段的函数 * * @access public * @param string $fieldvalue 字段值 * @param string $functionname 函数名称 * @param object $refObj 隶属对象 * @return string */ function EvalFunc($fieldvalue,$functionname,&$refObj) { $DedeFieldValue = $fieldvalue; $functionname = str_replace("{\"","[\"",$functionname); $functionname = str_replace("\"}","\"]",$functionname); $functionname = preg_replace("/'@me'|\"@me\"|@me/i",'$DedeFieldValue',$functionname); $functionname = "\$DedeFieldValue = ".$functionname; @eval($functionname.";"); //or die("$functionname"); if(empty($DedeFieldValue)) { return ''; } else { return $DedeFieldValue; } } /** * 获得一个外部变量 * * @access public * @param string $varname 变量名称 * @return string */ function GetGlobals($varname) { $varname = trim($varname); //禁止在模板文件读取数据库密码 if($varname=="dbuserpwd"||$varname=="cfg_dbpwd") { return ""; } //正常情况 if(isset($GLOBALS[$varname])) { return $GLOBALS[$varname]; } else { return ""; } } /** * 引入文件 * * @access public * @param string $filename 文件名 * @param string $ismake 是否需要编译 * @return string */ function IncludeFile($filename, $ismake='no') { global $cfg_df_style; $restr = ''; if($filename=='') { return ''; } if( file_exists(DEDEROOT."/templets/".$filename) ) { $okfile = DEDEROOT."/templets/".$filename; } else if(file_exists(DEDEROOT.'/templets/'.$cfg_df_style.'/'.$filename) ) { $okfile = DEDEROOT.'/templets/'.$cfg_df_style.'/'.$filename; } else { return "无法在这个位置找到: $filename"; } //编译 if($ismake!="no") { require_once(DEDEINC."/channelunit.func.php"); $dtp = new DedeTagParse(); $dtp->LoadTemplet($okfile); MakeOneTag($dtp,$this->refObj); $restr = $dtp->GetResult(); } else { $fp = @fopen($okfile,"r"); while($line=fgets($fp,1024)) $restr.=$line; fclose($fp); } return $restr; } } /********************************************** //class DedeAttribute Dede模板标记属性集合 function c____DedeAttribute(); **********************************************/ //属性的数据描述 class DedeAttribute { var $Count = -1; var $Items = ""; //属性元素的集合 //获得某个属性 function GetAtt($str) { if($str=="") { return ""; } if(isset($this->Items[$str])) { return $this->Items[$str]; } else { return ""; } } //同上 function GetAttribute($str) { return $this->GetAtt($str); } //判断属性是否存在 function IsAttribute($str) { if(isset($this->Items[$str])) return TRUE; else return FALSE; } //获得标记名称 function GetTagName() { return $this->GetAtt("tagname"); } // 获得属性个数 function GetCount() { return $this->Count+1; } } /******************************* //属性解析器(本版本中已经支持使用\'这种语法,和用.间隔表示name属性,如 field.body) function c____DedeAttributeParse(); ********************************/ class DedeAttributeParse { var $sourceString = ""; var $sourceMaxSize = 1024; var $cAttributes = ""; var $charToLow = TRUE; function SetSource($str='') { $this->cAttributes = new DedeAttribute(); $strLen = 0; $this->sourceString = trim(preg_replace("/[ \r\n\t]{1,}/"," ",$str)); //为了在function内能使用数组,这里允许对[ ]进行转义使用 $this->sourceString = str_replace('\]',']',$this->sourceString); $this->sourceString = str_replace('[','[',$this->sourceString); /* $this->sourceString = str_replace('\>','>',$this->sourceString); $this->sourceString = str_replace('<','>',$this->sourceString); $this->sourceString = str_replace('{','{',$this->sourceString); $this->sourceString = str_replace('\}','}',$this->sourceString); */ $strLen = strlen($this->sourceString); if($strLen>0 && $strLen <= $this->sourceMaxSize) { $this->ParseAttribute(); } } //解析属性 function ParseAttribute() { $d = ''; $tmpatt = ''; $tmpvalue = ''; $startdd = -1; $ddtag = ''; $hasAttribute=FALSE; $strLen = strlen($this->sourceString); $this->cAttributes->Items = array(); // 获得Tag的名称,解析到 cAtt->GetAtt('tagname') 中 for($i=0; $i<$strLen; $i++) { if($this->sourceString[$i]==' ') { $this->cAttributes->Count++; $tmpvalues = explode('.', $tmpvalue); $this->cAttributes->Items['tagname'] = ($this->charToLow ? strtolower($tmpvalues[0]) : $tmpvalues[0]); if(isset($tmpvalues[1]) && $tmpvalues[1]!='') { $this->cAttributes->Items['name'] = $tmpvalues[1]; } $tmpvalue = ''; $hasAttribute = TRUE; break; } else { $tmpvalue .= $this->sourceString[$i]; } } //不存在属性列表的情况 if(!$hasAttribute) { $this->cAttributes->Count++; $tmpvalues = explode('.', $tmpvalue); $this->cAttributes->Items['tagname'] = ($this->charToLow ? strtolower($tmpvalues[0]) : $tmpvalues[0]); if(isset($tmpvalues[1]) && $tmpvalues[1]!='') { $this->cAttributes->Items['name'] = $tmpvalues[1]; } return ; } $tmpvalue = ''; //如果字符串含有属性值,遍历源字符串,并获得各属性 for($i; $i<$strLen; $i++) { $d = $this->sourceString[$i]; //查找属性名称 if($startdd==-1) { if($d != '=') { $tmpatt .= $d; } else { if($this->charToLow) { $tmpatt = strtolower(trim($tmpatt)); } else { $tmpatt = trim($tmpatt); } $startdd=0; } } //查找属性的限定标志 else if($startdd==0) { switch($d) { case ' ': break; case '"': $ddtag = '"'; $startdd = 1; break; case '\'': $ddtag = '\''; $startdd = 1; break; default: $tmpvalue .= $d; $ddtag = ' '; $startdd = 1; break; } } else if($startdd==1) { if($d==$ddtag && ( isset($this->sourceString[$i-1]) && $this->sourceString[$i-1]!="\\") ) { $this->cAttributes->Count++; $this->cAttributes->Items[$tmpatt] = trim($tmpvalue); $tmpatt = ''; $tmpvalue = ''; $startdd = -1; } else { $tmpvalue .= $d; } } }//for //最后一个属性的给值 if($tmpatt != '') { $this->cAttributes->Count++; $this->cAttributes->Items[$tmpatt] = trim($tmpvalue); } //print_r($this->cAttributes->Items); }// end func }