/*********************************************
* 程序名:Luhd 轻型php模板编译类
* 版本: v1.0.2
* php版本要求 php ver5.2.0 或以上 
* 提供者 tyds qq382596765 email tyds1@
*                   msn: luhdok@
* 欢迎技术交流 欢迎索要使用手册
***********************************************/
// Luhd 轻型php模板编译类定义文件


// CodeIgniter 框架下打开以下语句
// if (! defined('BASEPATH')) exit('No direct script access allowed');
class Tydsparser {
   var  $left_delimiter = '{';
   var  $right_delimiter = '}';
   var $template_dir = 'microtpl';
   var $compile_dir = 'cache';
   var $html_dir = 'cache/html';
   var  $force_compile = false;
   var  $force_html =false;
   var  $exp_time = 0;
   var  $html_time = 0;
   var  $d_time=0;
   var $ftpl_var = array();
    var $starttime =0.00;
   var $char_code_re = '';
public function   __construct($config = array()){
      $this->initialize($config);
        // CodeIgniter 框架下打开以下语句
   //   log_message('debug', "Tydsparser Class Initialized");
   }
private function initialize($config = array())
   {
      $path_parts = pathinfo(__FILE__);
      $basedir = $path_parts["dirname"] ; 
      clearstatcache();
     if (count($config) > 0)
     {
         if(!empty($config['left_tag'])&&!empty($config['right_tag'])){
         $this->left_delimiter=$config['left_tag'];
         $this->right_delimiter=$config['right_tag'];
      }
      if (!empty($config['template_dir'])){
         $this->template_dir=THEROOT.$config['template_dir'];
      }else{$this->template_dir=THEROOT.$this->template_dir;}
      if (!empty($config['compile_dir'])&&!empty($config['html_dir']))
      {
         $this->compile_dir=THEROOT.$config['compile_dir'];
         $this->html_dir=THEROOT.$config['html_dir'];
      }else{
         $this->compile_dir=THEROOT.$this->compile_dir;
         $this->html_dir=THEROOT.$this->html_dir;
      }
      if (!empty($config['exp_time'])&&preg_match('/\d+/', $config['exp_time']))
      {
         $this->exp_time=$config['exp_time'];
      }
      if (!empty($config['html_time'])&&preg_match('/\d+/', $config['html_time']))
      {
         $this->exp_time=$config['html_time'];
      }
      if (!empty($config['datestr'])){
date_default_timezone_set(PRC);
$Dstrp = '/^\s*([1-9]\d{3})\s*[\-]?\s*(0?[1-9]|1[0-2])?\s*[\-]?\s*([0-2]?\d|3[01])?\s*([0-1]?\d|2[0-3])?\s*[:]?\s*([0-5]?\d)?\s*[:]?\s*([0-5]?\d)?$/';
if (preg_match($Dstrp,$config['datestr'],$time_arr)){
   list($all, $Y,$M,$d,$H,$m,$S) = $time_arr;
   $nowstr = date("Y-m-d H:i:s");
   preg_match($Dstrp ,$nowstr,$now_arr);
   list($alln, $Yn,$Mn,$dn,$Hn,$mn,$Sn) = $now_arr;
   $Y=is_null($Y)?$Yn:$Y;
   $M=is_null($M)?$Mn:$M;
   $d=is_null($d)?$dn:$d;
   $H=is_null($H)?$Hn:$H;
   $m=is_null($m)?$mn:$m;
   $S=is_null($S)?$Sn:$S;
$ms = mktime($H,$m,$S,$M,$d,$Y);         
   $this->d_time=$ms;
         }
      }
     }
  $re["gbk"]     = "[\x20-\x7e]|[\x81-\xfe][\x40-\xfe]"; 
  $re["gb2312"]  = "[\x20-\x7e]|[\xb0-\xf7][\xa0-\xfe]";
  $re["utf8"]   = "[\x20-\x7e]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}";
  $re["big5"]   = "[\x20-\x7e]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])";
  $this->char_code_re =  $re["utf8"];
   $this->create($this->compile_dir);
   $this->create($this->html_dir);
  }
   
public function __destruct(){
      unset($this->_section,$this->ftpl_var);
   }
 
private function mysubstr($str,  $strlen, $suffix='') {
  preg_match_all( '/'.$this->char_code_re.'/', $str, $match);
  if(count($match[0]) <= $strlen) return $str;
  $slice = join("",array_slice($match[0], 0, $strlen));
  $slice = $slice.$suffix;
  return $slice;
}
public function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
private function var_or_value($equalvalue)
{
   $equalvalue = trim($equalvalue);
   if(preg_match('/^\$\w([\w\[\]\$]*[\w\]])*/',$equalvalue))
      {return $this->parse_vars($equalvalue); }
   elseif(preg_match('/^[\'](.+)[\']$/',$equalvalue,$matches))
      {return $equalvalue;  }
   elseif(preg_match('/^["](.+)["]$/',$equalvalue,$matches))
      { return $equalvalue;  }
   elseif(preg_match('/^\d+$/',$equalvalue,$matches))
      {return $equalvalue;  }
   elseif(strtolower($equalvalue) == "true" || strtolower($equalvalue) == "false" || strtolower($equalvalue) == "null")
      {return $equalvalue;  }
   elseif(strlen($equalvalue) == 0)
      {return "''";  }
   else{
      $equalvalue =str_replace("\'", "'", $equalvalue);
      $equalvalue ="'".str_replace("'", "\'", $equalvalue)."'";
    return $equalvalue;  }
}   
protected function create($dir){
      if (!is_dir($dir))
      {
         $temp = explode('/',$dir);
         $cur_dir = '';
         for($i=0;$i          {
            $cur_dir .= $temp[$i].'/';
            if (!is_dir($cur_dir))
            {
               @mkdir($cur_dir,0777);
               @fopen("$cur_dir/index.htm","a");
            }
         }
      }
   }
private function write_file($file_name,$content){
      $compiledfile_url = $this->get_compiledfile_url($file_name);
      if(!is_dir($this->compile_dir)){
         $this->create($this->compile_dir);
      }
      if(!is_writable($this->compile_dir)){
         $this->show_messages("请先将编译文件夹".$this->compile_dir."和该文件夹中的所有文件的属性改成777。");
      }
      $fp = fopen($compiledfile_url,'wb');
      fwrite($fp,$content);
      fclose($fp);
      chmod($compiledfile_url,0777);
   }
public function show_messages($message){
      echo $message;
      exit;
   }
public function assign($vars,$value=null){
      if(is_array($vars)){
         foreach($vars as $key => $val){
            if($key != ''){
               $this->ftpl_var[$key] = $val;
            }
         }
      }
      else{
         if(is_string($vars) && $vars != ''){
            $this->ftpl_var[$vars] = $value;
         }else
         {$this->show_messages('assign()函数和 {assign...}模板语句里,
第一个参数必须是数组或字符串类型');}
      }
   }
public function display($file_name, $in_ci=false){
       $this->starttime = $this->microtime_float();
      error_reporting(E_ALL ^ E_NOTICE);
       $show_content = $this->fetch($file_name);
        if ($in_ci){
            $CI =& get_instance();
              $CI->output->append_output($show_content);
      }else{
      echo($show_content );
      }
   }
private function fetch($file_name){
      $compiledfile_url = $this->get_compiledfile_url($file_name);
      ob_start();
      $this->compile($file_name);
      include($compiledfile_url);
      $content = ob_get_contents();
      ob_end_clean();
      return $content;
   }
public function to_html($filename,$addname="",$pagenumber=1, $in_ci=false){
       $this->starttime = $this->microtime_float(); 
      $compiledfile_url = $this->get_compiledfile_url($filename);
      $this->compile($filename);
      if(!$this->is_html($filename,$addname,$pagenumber)){
         ob_start();
         if (!empty($addname))$filename.="_".$addname;
         if ($pagenumber>1)$filename.="_".$pagenumber;
         $fn=$this->get_html_url($filename);
         include($compiledfile_url);
         $fs=fopen($fn,'wb');
         fwrite($fs,ob_get_contents());
         fclose($fs);
         ob_clean();
         chmod($fn,0777);
      }else{
         if (!empty($addname))$filename.="_".$addname;
         if ($pagenumber>1)$filename.="_".$pagenumber;
      }
        if ($in_ci){
          ob_start();
         include($this->get_html_url($filename));
          $content = ob_get_contents();
          ob_end_clean();
         $CI =& get_instance();
          $CI->output->append_output($content);
      }else{
          include($this->get_html_url($filename));      
      }
   }
public function get_html($filename,$addname="",$pagenumber=1, $in_ci=false){
       $this->starttime =$this->microtime_float();
      if ($this->is_compiled($filename) && $this->is_html($filename,$addname,$pagenumber)) {
         if (!empty($addname))$filename.="_".$addname;
         if ($pagenumber>1)$filename.="_".$pagenumber;
            if ($in_ci){
              ob_start();
             include($this->get_html_url($filename));
              $content = ob_get_contents();
              ob_end_clean();
             $CI =& get_instance();
              $CI->output->append_output($content);
          }else{
              include($this->get_html_url($filename));      
              exit;
           }
      }else{
         $this->force_html=1;
      }
   }
public function outtime(){
        $end=$this->microtime_float();
      if ($this->starttime>0) 
      {$outtime = number_format(($end-$this->starttime)*1000,1);
      $showstr = '编译时间为:'.number_format(($end-$this->starttime)*1000,1).'毫秒';
      return $outtime;
      } 
       return 0;
   }
public function empty_vars(){
    $this->ftpl_var = array();
    return true;
}
   
protected function get_sourcefile_url($file_name){
      return preg_match('/\/$/',$this->template_dir)?$this->template_dir.$file_name:$this->template_dir.'/'.$file_name;
   }
protected function get_compiledfile_url($file_name){
      return preg_match('/\/$/',$this->compile_dir)?$this->compile_dir.$file_name.'.php':$this->compile_dir.'/'.$file_name.'.php';
   }
protected function get_html_url($file_name){
      return preg_match('/\/$/',$this->html_dir)?$this->html_dir.$file_name.'.html':$this->html_dir.'/'.$file_name.'.html';
   }
 
public function _quote($val){
      return preg_quote($val,'/');
   }
protected function is_compiled($file_name){
      if($this->force_compile){
         return false;
      }
      else{
         $sourcefile_url = $this->get_sourcefile_url($file_name);
         $compiledfile_url = $this->get_compiledfile_url($file_name);
         if(!file_exists($compiledfile_url) || filemtime($sourcefile_url) > filemtime($compiledfile_url)){
                clearstatcache();
            return false;
         }
         elseif($this->exp_time && time()-filemtime($compiledfile_url)>$this->exp_time){
                clearstatcache();
            return false;
         }
         else {
                clearstatcache();
            return true;
         }
      }
   }
protected function is_html($file_name,$addname='',$pagenumber=1){
      if($this->force_html){
         return false;
      }
      else{
         $html_name=(empty($addname))?$file_name:$file_name."_".$addname;
         $html_name=($pagenumber>1)?$html_name."_".$pagenumber:$html_name;
         $compiledfile_url = $this->get_compiledfile_url($file_name);
         $html_url=$this->get_html_url($html_name);
         if(!file_exists($html_url) || (filemtime($html_url) < filemtime($compiledfile_url))){
                clearstatcache();
            return false;
         }
         elseif($this->html_time && time()-filemtime($html_url)>$this->html_time){
                clearstatcache();
            return false;
         }
         elseif ($this->d_time && $this->d_time > filemtime($html_url)){
                clearstatcache();
            return false;
         }
         else{
                clearstatcache();
            return true;
         }
      }
   }
protected function compile($file_name){
      $content = $this->get_contents($file_name);
      $content = $this->parse_include($content);
      if(!$this->is_compiled($file_name)){
         $content = $this->parse_assign($content);
         $content = $this->parse_variable($content);
         $content = $this->parse_include_php($content);
         $content = $this->parse_php($content);
         $content = $this->parse_code($content);
         $content = $this->parse_if($content);
         $content = $this->parse_elseif($content);
         $content = $this->parse_else($content);
         $content = $this->parse_section($content);
         $content = $this->parse_sectionelse($content);
         $content = $this->parse_foreach($content);
         $content = $this->parse_foreachelse($content);
         $content = $this->parse_cycle($content);
         $content = $this->parse_html($content);
         $content = $this->parse_end($content);
           $content = $this->parse_substr($content);
           $content = $this->parse_note($content);
            $thepathinfo = pathinfo(__FILE__);
            $pluginsdir=$thepathinfo["dirname"].'/plugins';
         if (is_dir($pluginsdir))
          {
            if ($dh = @opendir($pluginsdir)) {
                   while (($filenm = readdir($dh)) !== false ) {
                       if( $filenm !='.' AND $filenm !='..'){
                        $plugin_content = file_get_contents($pluginsdir.'/'.$filenm);
                     $check_regular = '/if\s*\(\s*!function_exists\s*\(\s*\'\w+\'\s*\)\s*\)\s*\{\s*function\s*(\w+)\s*\(\$content\s*,\s*&\$parser\s*\)\s*\{[\s\S]*?return\s*\$content;\s*\}\s*\}\s*/i';           
                      if(preg_match_all($check_regular,$plugin_content,$plugin_arr)){
                     $funtion_arr = $plugin_arr[1];
                     include_once($pluginsdir.'/'.$filenm);
                         foreach ($funtion_arr as $value){
                            $backcontent = call_user_func($value, $content,$this);
                               if (is_string($backcontent)){$content =$backcontent; }
                            }
                          }
                    }
               }
                   closedir($dh);
                  }
            }
           $this->write_file($file_name,$content);
      }
   }
private function get_contents($file_name){
      $sourcefile_url = $this->get_sourcefile_url($file_name);
      if(!file_exists($sourcefile_url) || !($content = file_get_contents($sourcefile_url))) {
         $this->show_messages("无法读取模板文件{$file_name},请检查文件是否存在。");
      }
      return $content;
   }
// 模板语言例句:{code} $mm = 1; {/code} 
protected function parse_code($content){
      $code_regular = '/'.$this->_quote($this->left_delimiter).'code'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/code'.$this->_quote($this->right_delimiter).'/is';
      if(preg_match_all($code_regular,$content,$code_arr)){
         $content = preg_replace($code_regular,'',$content);
         $ext_arr = $code_arr[1];
         foreach ($code_arr[1] as $key=>$value){
            if(preg_match_all('/\$\w(?:[\w\[\]\$]*[\w\]])*/',$value,$code_arr1)){
               foreach ($code_arr1[0] as $key1 => $value1){
                  $ext_arr[$key] = preg_replace('/'.$this->_quote($value1).'/',$this->parse_vars($value1),$ext_arr[$key],1);
               }
               $content = preg_replace('/'.$this->_quote($code_arr[1][$key]).'/',$ext_arr[$key],$content,1);
            }
         }
      }
      return $content;
   }
// 模板语言例句: {php} $mm = 1; {/php}
protected function parse_php($content){
      $php_regular = '/'.$this->_quote($this->left_delimiter).'php'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/php'.$this->_quote($this->right_delimiter).'/is';
      $content = preg_replace($php_regular,"",$content);
      return $content;
   }
protected  function parse_vars($vars){
           $old_vars =$vars;
         $vars = preg_replace('/[\$]+/','$',$vars);
         $vars = preg_replace('/[\'"]+/','',$vars);
         $vars = preg_replace('/(\[\])+/','',$vars);
         $vars = preg_replace('/(\[\w+)\[/','\1][',$vars);
         $vars = preg_replace('/\](\w+\])/','][\1',$vars);
         $vars = preg_replace('/\](\w+)\[/','][\1][',$vars);
         if(preg_match('/\$[\]\[]/',$vars)){$this->show_messages("模板变量$old_vars格式错误,\$后要有变量名。解析".$old_vars."时出错");}
         $vars = preg_replace('/\$(\w+)/','$this->ftpl_var[\'\1\']',$vars);
         $vars = preg_replace('/\[(\w+)\]/','[\'\1\']',$vars);
       if (strpos($vars, "['section']") === false){
         eval('if(!isset('.$vars.')) $xx="no"; unset($xx);');
         }
       return $vars ;
}
// 模板语言例句:{$xxx[xxx]}   {$xxx[$xxx]}  {$xxx[$xxx[aaa]]} 
protected function parse_variable($content){
      $variable_regular = '/'.$this->_quote($this->left_delimiter).'(\$\w(?:[\w\[\]\$]*[\w\]])*)'.$this->_quote($this->right_delimiter).'/';
      if(preg_match_all($variable_regular,$content,$variable_arr)){
         foreach ($variable_arr[1] as $key=>$value){
              $value =  $this->parse_vars($value);
               $replacestr = $value;
               if (preg_match('/^\$\w(?:[\w\[\]\$]*[\w\]])*/',$value)) {
                  $realv ='';
               if (strpos($value, "['section']") === false){
                  eval('if(isset('.$value.')) $realv = '.$value.';'); 
               }
                  if(is_array($realv))
                  {
                   $value = var_export($realv,1);
             $replacestr ='"'.str_replace(",)", ")",  str_replace('"', '\"', str_replace("\n", "",   $value))).'"' ;
                   }
                   elseif(is_bool($realv))
                   {
                    $replacestr =$realv?"'true'":"'false'" ;
                   }
                }
            $rep = "             $rep .= $replacestr;
            $rep .= ";?>";
            $content = preg_replace('/'.$this->_quote($variable_arr[0][$key]).'/',$rep,$content,1);
         }
      }
      return $content;
   }
// 模板语言例句:      {assign var="ll" value="vvv"}
protected function parse_assign($content){
  $assign_regular ='/'.$this->_quote($this->left_delimiter).'assign\s+var\s*=\s*([\'"]?\w+[\'"])?\s+value\s*=\s*(.+?)'.$this->_quote($this->right_delimiter).'/';
if(preg_match_all($assign_regular,$content,$assign_arr)){
   foreach ($assign_arr[0] as $key=>$value){
     $varstr = $this->var_or_value($assign_arr[1][$key]);
     $valuestr =trim($assign_arr[2][$key]);
     $valuestr = $this->var_or_value($valuestr);
    //eval("\$this->assign($varstr,$valuestr);");
     $rep ='ftpl_var['.$varstr.'] = '.$valuestr.';?>';
   /*$rep =    "assign($varstr,$valuestr);?>";*/
   $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
   }         
}
return $content;
}
   
protected function _cycle($value){
$thevalue = $value;
      static $cycle_index, $thevalue;
      if(!isset($cycle_index)) $cycle_index = 0;
      if($value !== $thevalue) $cycle_index = 0;
   if(is_string($value))   
   {   $thevalue = $value;
      $cycle_arr = explode(',',$value);
      $cycle_value = $cycle_arr[$cycle_index];
      if($cycle_index >= count($cycle_arr)-1) $cycle_index = 0;
      else $cycle_index++;
      return $cycle_value;
    }else
   {$this->show_messages('循环值必须是字符串类型');}
}
// 模板语言例句:{cycle values = "xxx"}
protected function parse_cycle($content){
      $cycle_regular = '/'.$this->_quote($this->left_delimiter).'cycle\s+values\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|.+)'.$this->_quote($this->right_delimiter).'/iU';
   
if(preg_match_all($cycle_regular,$content,$cycle_arr))
{
   foreach ($cycle_arr[0] as $key=>$value){
         $cylevalue =$cycle_arr[1][$key];
         $cylevalue = trim($cylevalue);
        $cyclestr = $this->var_or_value($cylevalue);
    $rep =    "_cycle($cyclestr);?>";
   $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
   }         
}      
      return $content;
   }
protected function _html($html,$name,$options,$selected,$opt1,$opt2,$opt3){
if(!is_string($name))   {$this->show_messages('{html_...}语句的name值必须是字符串类型');}
if(!is_array($options))   {$this->show_messages('{html_...}语句的options值必须是数组');}
if(is_int($opt1)) $separator = $opt1;
elseif(is_int($opt2)) $separator = $opt2;
elseif(is_int($opt3)) $separator = $opt3;
else $separator = 0;
if(strtolower($opt1)=='left' OR strtolower($opt1)=='right' ) $labelposition = $opt1;
elseif(strtolower($opt2)=='left' OR strtolower($opt2)=='right' ) $labelposition = $opt2;
elseif(strtolower($opt3)=='left' OR strtolower($opt3)=='right' ) $labelposition = $opt3;
else $labelposition = 'right';
if(strtolower($opt1)=='disabled') $isdisabled = $opt1;
elseif(strtolower($opt2)=='disabled' ) $isdisabled = $opt2;
elseif(strtolower($opt3)=='disabled') $isdisabled = $opt3;
else $isdisabled = '';
      switch ($html){
         case 'options':
            $select="";
               if (is_array($options)){
               foreach ($options as $key=>$value){
                  $isselected=($selected==$key)?'selected':'';
                  $select.="$value";
               }
            }
            $select.="";
            return $select;
            break;
         case 'checkboxes':
            $i=1;$check='';$separator_out='';
            if (is_array($options)){
               foreach ($options as $key=>$value){
                  if ($separator>0) $separator_out=($i%$separator==0)?'
':'';
                  if (!is_array($selected) && !is_object($selected)) { settype($selected, 'array');};
                    $isselected=in_array($key,$selected)?'checked':'';
                  if($labelposition=="left")
                  {   $check.="$value $separator_out";                      
                  }else{
                        $check.="$value $separator_out";                      
                  }
                  $i++;
               }
            }
            return $check;
            break;
         case 'radios':
            $i=1;$check='';$separator_out='';
            if (is_array($options)){
               foreach ($options as $key=>$value){
                  if ($separator>0) $separator_out=($i%$separator==0)?'
':'';
                  $isselected=($selected==$key)?'checked':'';
                  if($labelposition=="left")
                  {   $check.="$value $separator_out";      
                  }else{
                     $check.="$value $separator_out";
                  }
                  $i++;
               }
            }
            return $check;
            break;
      }
   }
/* 模板语言例句:
*   {html_radios name=$aaa options=$adata checked=$checked separator=2 labelposition=left disabled}
*   {html_checkboxes name=$aaa options=$adata selected=$checked separator=2}
*   {html_options name=$aaa options=$adata selected=$checked separator=2}
**/
protected function parse_html($content){
      $option_regular = '/'.$this->_quote($this->left_delimiter).'html_(\w+)\s+name\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+options\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*)(\s+(?:selected|checked)\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*))?((\s+(?:separator\s*=|labelposition\s*=)?\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)){0,3})\s*'.$this->_quote($this->right_delimiter).'/isU';
      if(preg_match_all($option_regular,$content,$option_arr)){//print_r($option_arr);
         foreach ($option_arr[0] as $key=>$value){
            $name = $this->var_or_value($option_arr[2][$key]);
            $options = $this->var_or_value($option_arr[3][$key]);
            $selected =  $this->var_or_value($option_arr[5][$key]);
                $otherstr =ltrim(trim($option_arr[6][$key]));
            if (strlen($otherstr) > 0){
                    $otherstr = preg_replace('/\s+/',',',$otherstr);
                $othera = explode ( ',', $otherstr);
                     if(!isset($othera[1])){$othera[1] ='';$othera[2] ='';}
                     else{
                   if(!isset($othera[2])){$othera[2] ='';}
                }    
            }else
            {$othera[0] ='';$othera[1] ='';$othera[2] ='';}
      $temparry = array();
      foreach ($othera as $thekey=>$thevalue){
        if(preg_match('/separator\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)/',$thevalue,$matches)){
            $temparry[] = $this->var_or_value($matches[1]);
              unset($matches);
        }
       elseif(preg_match('/labelposition\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)/',$thevalue,$matches)){
            $temparry[] = $this->var_or_value($matches[1]);
              unset($matches);
        }   
        else{
           $temparry[] =  $this->var_or_value($thevalue);
        }      
      }
       $othera = $temparry;
       unset($temparry);
            switch ($option_arr[1][$key]){
               case 'options':
                  $rep =    "_html('".$option_arr[1][$key]."',".$name.",".$options.",".$selected.",".$othera[0].",".$othera[1].",".$othera[2].");\r\n?>";
                  $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
                  break;
               case 'checkboxes':
                  $rep =    "_html('".$option_arr[1][$key]."',".$name.",".$options.",".$selected.",".$othera[0].",".$othera[1].",".$othera[2].");\r\n?>";
                  $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
                  break;
               case 'radios':
                  $rep =    "_html('".$option_arr[1][$key]."',".$name.",".$options.",".$selected.",".$othera[0].",".$othera[1].",".$othera[2].");\r\n?>";
                  $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
                  break;
            }
         }
      }
      return $content;
   }
// 模板语言例句:{if $cont.id > 0} 该语句和 {elseif ...}语句的里 条件部分除了会解析该部分里的模板变量外, 不会作任何修改, 所以需注意条件的合理性,文字意义的字符需要用引号包围。这点不同于其他语句。
protected function parse_if($content){
      $if_regular = '/'.$this->_quote($this->left_delimiter).'if\s(.+)'.$this->_quote($this->right_delimiter).'/isU';
      if(preg_match_all($if_regular,$content,$if_arr)){
          foreach ($if_arr[0] as $key=>$value){
            if(preg_match_all('/\$\w(?:[\w\[\]\$]*[\w\]])*/',$value,$if_arr1)){
               foreach ($if_arr1[0] as $key1=>$value1){
                  $if_arr[1][$key] = preg_replace('/'.$this->_quote($value1).'/',$this->parse_vars($value1),$if_arr[1][$key],1);
               }
                   $replacestr = str_replace('<','<',$if_arr[1][$key]);
               $rep =    "";
               $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
            }
            else{
                   $replacestr = str_replace('<','<',$if_arr[1][$key]);
               $rep =    "";
               $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);            
            }
         }
      }
      return $content;      
}
// 模板语言例句: {elseif $action=='useradd_1'} 
protected function parse_elseif($content){
      $if_regular = '/'.$this->_quote($this->left_delimiter).'elseif\s(.+)'.$this->_quote($this->right_delimiter).'/isU';
      if(preg_match_all($if_regular,$content,$if_arr)){
         foreach ($if_arr[0] as $key=>$value){
            if(preg_match_all('/\$\w(?:[\w\[\]\$]*[\w\]])*/',$value,$if_arr1)){
               foreach ($if_arr1[0] as $key1=>$value1){
                  $if_arr[1][$key] = preg_replace('/'.$this->_quote($value1).'/',$this->parse_vars($value1),$if_arr[1][$key],1);
               }
                   $replacestr = str_replace('<','<',$if_arr[1][$key]);
               $rep =    "";
               $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
            }
            else{
                   $replacestr = str_replace('<','<',$if_arr[1][$key]);
               $rep =    "";
               $content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
            }
         }
      }
      return $content;
   }
// 模板语言: {else}
protected function parse_else($content){
      $else_regular = '/'.$this->_quote($this->left_delimiter).'else'.$this->_quote($this->right_delimiter).'/i';
      $rep = "";
      $content = preg_replace($else_regular,$rep,$content);
      return $content;
   }
// 模板语言例句:{section name=xxx loop=$myloopvar start=3 step=2}
protected function parse_section($content){
      $section_regular =  '/'.$this->_quote($this->left_delimiter).'section\s+name\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+loop\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*)(\s+start\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|\d+))?(\s+step\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|\d+))?'.$this->_quote($this->right_delimiter).'/';
      if(preg_match_all($section_regular,$content,$section_arr)){   
         foreach($section_arr[2] as $key=>$val){
            $loopvar = $this->parse_vars($val);
                $namevar =  $this->var_or_value($section_arr[1][$key]);
                $startvar =  $this->var_or_value($section_arr[4][$key]);
                $stepvar =  $this->var_or_value($section_arr[6][$key]);
                $basenamestr='$this->ftpl_var[\'section\']['.$namevar.']';
            $rep = array();
            $rep[] = "                 $rep[] = "if(!is_string($namevar)){\$this->show_messages('{section ...}语句的name值必须是字符串类型');}";
                $rep[] = "\$start_value=is_int($startvar)?$startvar:0;";
                $rep[] = "\$step_value =is_int($stepvar)?$stepvar:1;";
            $rep[] = $basenamestr."['name']  =".$namevar.";"; 
            $rep[] = $basenamestr."['start'] = \$start_value;";
            $rep[] = $basenamestr."['step'] = \$step_value;";
            $rep[] = $basenamestr."['loop'] = is_array({$loopvar})?count({$loopvar}):0;";
            $rep[] = $basenamestr."['total'] = ceil((".$basenamestr."['loop']-".$basenamestr."['start'])/".$basenamestr."['step']);";
            $rep[] = "if(".$basenamestr."['total'] > 0){";
            $rep[] = "    for(".$basenamestr."['index'] = ".$basenamestr."['start'], ".$basenamestr."['iteration'] = 1;";
            $rep[] = "       ".$basenamestr."['index'] <".$basenamestr."['loop'];";
            $rep[] = "       ".$basenamestr."['index'] += ".$basenamestr."['step'], ".$basenamestr."['iteration']++)";
            $rep[] = "    {";
            $rep[] = "       ".$basenamestr."['index_prev'] =".$basenamestr."['index'] - ".$basenamestr."['step'];";
            $rep[] = "      ".$basenamestr."['index_next'] = ".$basenamestr."['index'] +".$basenamestr."['step'];";
            $rep[] = "      ".$basenamestr."['first'] =(".$basenamestr."['iteration'] == 1);";
            $rep[] = "       ".$basenamestr."['last'] = (".$basenamestr."['iteration'] ==".$basenamestr."['total']);";
            $rep[] = "       ".$basenamestr."['rownum'] = ".$basenamestr."['iteration'];";
            $rep[] = "?>";
            $rs = implode("\r\n",$rep);
            $content = preg_replace('/'.$this->_quote($section_arr[0][$key]).'/s',$rs,$content,1);
            unset($rs);
         }
      }
      return $content;
   }
// 模板语言例句:{sectionelse}something{/section}
protected function parse_sectionelse($content){
      $sectionelse_regular = '/'.$this->_quote($this->left_delimiter).'sectionelse'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/section'.$this->_quote($this->right_delimiter).'/is';
      $content = preg_replace($sectionelse_regular,"\\1",$content);
      return $content;
   }
// 模板语言例句: {foreach name = myforeach1 key=foreachkey item=itemvalue from=$myarray}
protected function parse_foreach($content){
      $foreach_regular =  '/'.$this->_quote($this->left_delimiter).'foreach\s+(name\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+)?(key\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+)?item\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+from\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*)\s*'.$this->_quote($this->right_delimiter).'/';
      if(preg_match_all($foreach_regular,$content,$foreach_arr)){
         foreach($foreach_arr[6] as $key=>$val){
                $from = $this->parse_vars($val);
            $keystr  =  $this->var_or_value($foreach_arr[4][$key]);
            if (preg_match('/^[\$\'"]\w+/',$keystr)) {
                eval('if(is_string('.$keystr.') && strlen('.$keystr.") != 0 ){\$itemkey ='\$'.".$keystr .".' => ';}");
            } else {
                 $itemkey = "''";
            }
            $namestr= $this->var_or_value($foreach_arr[2][$key]);
            if (preg_match('/^[\$\'"]\w+/',$namestr)) {
                eval('if(is_string('.$namestr.') && strlen('.$namestr.') != 0 ){$name =\'"\'.'.$namestr.'.\'"\';}');
            } else {
                 $name = '';
            }
            $itemstr= $this->var_or_value($foreach_arr[5][$key]);
            if (preg_match('/^[\$\'"]\w+/',$itemstr)) {
                eval('if(is_string('.$itemstr.') && strlen('.$itemstr.") != 0 ){\$item ='\$'.".$itemstr.";}");
            } else {
                 $this->show_messages('{foreach ...}语句的item值必须是字符串');
            }
            $rep = array();
            $rep[] = '             $rep[]= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array');}";
            if (strlen($name) !=0) {
               $foreach_props = "\$this->ftpl_var['foreach'][$name]";
               $rep[]= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);";
               $rep[]= "if ({$foreach_props}['total'] > 0){";
               $rep[]= "    foreach (\$_from as $itemkey $item){";
               $rep[]= "        {$foreach_props}['iteration']++;";
                $rep[]= "        \$this->ftpl_var['foreach'][$name]['itemkey'] = ".substr($itemkey,0,strlen($itemkey)-4).";";
               $rep[]= "        \$this->ftpl_var['foreach'][$name]['item'] = $item;";   
            } else { 
               $rep[]= "if (count(\$_from)){";
               $rep[]= "    foreach (\$_from as $itemkey $item){";
               $rep[]= "        \$this->ftpl_var['foreach']['itemkey'] = ".substr($itemkey,0,strlen($itemkey)-4).";";
               $rep[]= "        \$this->ftpl_var['foreach']['item'] = $item;";   
            }
            $rep[]= '?>';
            $rs = implode("\r\n",$rep);
            $content = preg_replace('/'.$this->_quote($foreach_arr[0][$key]).'/s',$rs,$content,1);
            unset($rs,$name,$item,$from,   $key1,$itemkey,$rep,$keystr, $itemstr,$namestr);
         }
      }
      return $content;
   }
// 模板语言例句:{foreachelse}something{/foreach}
protected function parse_foreachelse($content){
      $sectionelse_regular = '/'.$this->_quote($this->left_delimiter).'foreachelse'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/foreach'.$this->_quote($this->right_delimiter).'/is';
      $content = preg_replace($sectionelse_regular,"\\1",$content);
      return $content;
   }
// 模板语言: {/foreach}   {/section}       {/if}
protected function parse_end($content){
      $section_end_regular = '/'.$this->_quote($this->left_delimiter).'\/section'.$this->_quote($this->right_delimiter).'/';
      $section_rep = "";
      $content = preg_replace($section_end_regular,$section_rep,$content);
      $if_end_regular = '/'.$this->_quote($this->left_delimiter).'\/if'.$this->_quote($this->right_delimiter).'/';
      $if_rep = "";
      $content = preg_replace($if_end_regular,$if_rep,$content);
      $if_end_regular = '/'.$this->_quote($this->left_delimiter).'\/foreach'.$this->_quote($this->right_delimiter).'/';
      $if_rep = "       unset(\$_form);
      \r\n} ?>";
      $content = preg_replace($if_end_regular,$if_rep,$content);
      return $content;
   }
// 模板语言例句:{include file = "xxx"}  当前目录是模板文件所在文件夹 因为该语句会编译模板文件, 再包含编译后的php文件, 所以, 这里只能是包含存储在设定的模板文件存储目录里的模板文件。 要包含其它文件, 请使用{include_php file = "xxx"} 语句
protected function parse_include($content){
   $include_regular ='/'.$this->_quote($this->left_delimiter).'include\s+file\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+\.*\w+[\'"]?)\s*'.$this->_quote($this->right_delimiter).'/iU';
         if(preg_match_all($include_regular,$content,$include_arr)){
              foreach ($include_arr[1] as $key => $value){
               $valuestr =  $this->var_or_value($value);
                eval('if(!is_string('.$valuestr.') || strlen('.$valuestr.") == 0 ){\$this->show_messages('必须有模板文件名');}else{\$this->compile(".$valuestr.");   }");      
                   $content =preg_replace('/'.$this->_quote($include_arr[0][$key]).'/s',"",$content,1);
                }
             }
      return $content;
   }
// 模板语言例句:{include_php file = "xxx"} 当前目录是php缓冲文件所在文件夹,如果在这个文件夹或其子目录下找不到文件,就从网站根目录开始找.
protected function parse_include_php($content){
   $include_php_regular ='/'.$this->_quote($this->left_delimiter).'include_php\s+file\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?[\w\.\/]+[\'"]?)\s*'.$this->_quote($this->right_delimiter).'/iU';
         if(preg_match_all($include_php_regular,$content,$include_php_arr)){
              foreach ($include_php_arr[1] as $key => $value){
               $valuestr =  $this->var_or_value($value);
                eval('if(!is_string('.$valuestr.') || strlen('.$valuestr.") == 0 ){\$this->show_messages('文件名不正确.');}");   
                   eval('if(file_exists(\''.$this->compile_dir.'\'."/".'.$valuestr.')){$thefilepath = \''.$this->compile_dir.'\'."/".'.$valuestr.';}else{$thefilepath = \''.THEROOT.'\'."/".'.$valuestr.';}');
                   $content =preg_replace('/'.$this->_quote($include_php_arr[0][$key]).'/s',"",$content,1);
                }
             }
      return $content;
  }
// 模板语言例句:{"下是三个html标签生成的模板语"|9...} 对文本值割尾输出
protected function parse_substr($content){
   $substr_regular ='/'.$this->_quote($this->left_delimiter).'\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|.+)\|(\d*)(\.{0,6})\s*'.$this->_quote($this->right_delimiter).'/iU';
         if(preg_match_all($substr_regular ,$content,$substr_arr)){
              foreach ($substr_arr[1] as $key => $value){
               $valuestr =  $this->var_or_value($value);
                   $substrlen= (int)$substr_arr[2][$key]; 
                   $suffix= "'".$substr_arr[3][$key]."'";
                eval('if(!is_string('.$valuestr.') || strlen('.$valuestr.") == 0 ){echo '$value 值不是字符.'; \$temsub='".$substr_arr[0][$key]."X'; }else{\$temsub=\$this->mysubstr(".$valuestr.', '.$substrlen.' , '.$suffix.');}');   
                   $content =preg_replace('/'.$this->_quote($substr_arr[0][$key]).'/s',$temsub,$content,1);
                }
             }
      return $content;
}
// 模板语言例句:{* 我在服务端模板里, 你看不到} 模板里的注释语句, 优势是, 这样的注释客户端绝对看不到
protected function parse_note($content){
   $note_regular ='/'.$this->_quote($this->left_delimiter).'\*.+'.$this->_quote($this->right_delimiter).'/iU';
         if(preg_match_all($note_regular ,$content,$note_arr)){
              foreach ($note_arr[0] as $key => $value){
               $valuestr ='';
                   $content =preg_replace('/'.$this->_quote($note_arr[0][$key]).'/s',$valuestr,$content,1);
                }
             }
      return $content;
}
}