Volist标签 bug改善

jerry thinkphp 2015年11月18日 收藏
mod 有点小问题,第103行
见下面代码
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------

  11. defined('THINK_PATH') or exit();
  12. /**
  13.  * CX标签库解析类
  14.  * @category   Think
  15.  * @package  Think
  16.  * @subpackage  Driver.Taglib
  17.  * @author    liu21st <liu21st@gmail.com>
  18.  */
  19. class TagLibCx extends TagLib {

  20.     // 标签定义
  21.     protected $tags   =  array(
  22.         // 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次
  23.         'php'       =>  array(),
  24.         'volist'    =>  array('attr'=>'name,id,offset,length,key,mod','level'=>3,'alias'=>'iterate'),
  25.         'foreach'   =>  array('attr'=>'name,item,key','level'=>3),
  26.         'if'        =>  array('attr'=>'condition','level'=>2),
  27.         'elseif'    =>  array('attr'=>'condition','close'=>0),
  28.         'else'      =>  array('attr'=>'','close'=>0),
  29.         'switch'    =>  array('attr'=>'name','level'=>2),
  30.         'case'      =>  array('attr'=>'value,break'),
  31.         'default'   =>  array('attr'=>'','close'=>0),
  32.         'compare'   =>  array('attr'=>'name,value,type','level'=>3,'alias'=>'eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq'),
  33.         'range'     =>  array('attr'=>'name,value,type','level'=>3,'alias'=>'in,notin,between,notbetween'),
  34.         'empty'     =>  array('attr'=>'name','level'=>3),
  35.         'notempty'  =>  array('attr'=>'name','level'=>3),
  36.         'present'   =>  array('attr'=>'name','level'=>3),
  37.         'notpresent'=>  array('attr'=>'name','level'=>3),
  38.         'defined'   =>  array('attr'=>'name','level'=>3),
  39.         'notdefined'=>  array('attr'=>'name','level'=>3),
  40.         'import'    =>  array('attr'=>'file,href,type,value,basepath','close'=>0,'alias'=>'load,css,js'),
  41.         'assign'    =>  array('attr'=>'name,value','close'=>0),
  42.         'define'    =>  array('attr'=>'name,value','close'=>0),
  43.         'for'       =>  array('attr'=>'start,end,name,comparison,step', 'level'=>3),
  44.         );

  45.     /**
  46.      * php标签解析
  47.      * @access public
  48.      * @param string $attr 标签属性
  49.      * @param string $content  标签内容
  50.      * @return string
  51.      */
  52.     public function _php($attr,$content) {
  53.         $parseStr = '<?php '.$content.?>';
  54.         return $parseStr;
  55.     }

  56.     /**
  57.      * volist标签解析 循环输出数据集
  58.      * 格式:
  59.      * <volist name="userList" id="user" empty="" >
  60.      * {user.username}
  61.      * {user.email}
  62.      * </volist>
  63.      * @access public
  64.      * @param string $attr 标签属性
  65.      * @param string $content  标签内容
  66.      * @return string|void
  67.      */
  68.     public function _volist($attr,$content) {
  69.         static $_iterateParseCache = array();
  70.         //如果已经解析过,则直接返回变量值
  71.         $cacheIterateId = md5($attr.$content);
  72.         if(isset($_iterateParseCache[$cacheIterateId]))
  73.             return $_iterateParseCache[$cacheIterateId];
  74.         $tag   =    $this->parseXmlAttr($attr,'volist');
  75.         $name  =    $tag['name'];
  76.         $id    =    $tag['id'];
  77.         $empty =    isset($tag['empty'])?$tag['empty']:'';
  78.         $key   =    !empty($tag['key'])?$tag['key']:'i';
  79.         $mod   =    isset($tag['mod'])?$tag['mod']:'2';
  80.         // 允许使用函数设定数据集 <volist name=":fun('arg')" id="vo">{$vo.name}</volist>
  81.         $parseStr   =  '<?php ';
  82.         if(0===strpos($name,':')) {
  83.             $parseStr   .= '$_result='.substr($name,1).';';
  84.             $name   = '$_result';
  85.         }else{
  86.             $name   = $this->autoBuildVar($name);
  87.         }
  88.         $parseStr  .=  'if(is_array('.$name.')): $'.$key.' = 0;';
  89.         if(isset($tag['length']) && '' !=$tag['length'] ) {
  90.             $parseStr  .= ' $__LIST__ = array_slice('.$name.','.$tag['offset'].','.$tag['length'].',true);';
  91.         }elseif(isset($tag['offset'])  && '' !=$tag['offset']){
  92.             $parseStr  .= ' $__LIST__ = array_slice('.$name.','.$tag['offset'].',null,true);';
  93.         }else{
  94.             $parseStr .= ' $__LIST__ = '.$name.';';
  95.         }
  96.         $parseStr .= 'if( count($__LIST__)==0 ) : echo "'.$empty.'" ;';
  97.         $parseStr .= 'else: ';
  98.         $parseStr .= 'foreach($__LIST__ as $key=>$'.$id.'): ';
  99.         //改善后
  100.         $parseStr .= '++$'.$key.';';
  101.         $parseStr .= '$mod = ($'.$key.' % '.$mod.' );';
  102.         $parseStr .= '?>';
  103.         /*改善前
  104.         $parseStr .= '$mod = ($'.$key.' % '.$mod.' );';
  105.         $parseStr .= '++$'.$key.';?>';*/
  106.         
  107.         $parseStr .= $this->tpl->parse($content);
  108.         $parseStr .= '<?php endforeach; endif; else: echo "'.$empty.'" ;endif; ?>';
  109.         $_iterateParseCache[$cacheIterateId] = $parseStr;

  110.         if(!empty($parseStr)) {
  111.             return $parseStr;
  112.         }
  113.         return ;
  114.     }

  115.     /**
  116.      * foreach标签解析 循环输出数据集
  117.      * @access public
  118.      * @param string $attr 标签属性
  119.      * @param string $content  标签内容
  120.      * @return string|void
  121.      */
  122.     public function _foreach($attr,$content) {
  123.         static $_iterateParseCache = array();
  124.         //如果已经解析过,则直接返回变量值
  125.         $cacheIterateId = md5($attr.$content);
  126.         if(isset($_iterateParseCache[$cacheIterateId]))
  127.             return $_iterateParseCache[$cacheIterateId];
  128.         $tag        =   $this->parseXmlAttr($attr,'foreach');
  129.         $name       =   $tag['name'];
  130.         $item       =   $tag['item'];
  131.         $key        =   !empty($tag['key'])?$tag['key']:'key';
  132.         $name       =   $this->autoBuildVar($name);
  133.         $parseStr   =   '<?php if(is_array('.$name.')): foreach('.$name.' as $'.$key.'=>$'.$item.'): ?>';
  134.         $parseStr  .=   $this->tpl->parse($content);
  135.         $parseStr  .=   '<?php endforeach; endif; ?>';
  136.         $_iterateParseCache[$cacheIterateId] = $parseStr;
  137.         if(!empty($parseStr)) {
  138.             return $parseStr;
  139.         }
  140.         return ;
  141.     }

  142.     /**
  143.      * if标签解析
  144.      * 格式:
  145.      * <if condition=" $a eq 1" >
  146.      * <elseif condition="$a eq 2" />
  147.      * <else />
  148.      * </if>
  149.      * 表达式支持 eq neq gt egt lt elt == > >= < <= or and || &&
  150.      * @access public
  151.      * @param string $attr 标签属性
  152.      * @param string $content  标签内容
  153.      * @return string
  154.      */
  155.     public function _if($attr,$content) {
  156.         $tag        =   $this->parseXmlAttr($attr,'if');
  157.         $condition  =   $this->parseCondition($tag['condition']);
  158.         $parseStr   =   '<?php if('.$condition.'): ?>'.$content.'<?php endif; ?>';
  159.         return $parseStr;
  160.     }

  161.     /**
  162.      * else标签解析
  163.      * 格式:见if标签
  164.      * @access public
  165.      * @param string $attr 标签属性
  166.      * @param string $content  标签内容
  167.      * @return string
  168.      */
  169.     public function _elseif($attr,$content) {
  170.         $tag        =   $this->parseXmlAttr($attr,'elseif');
  171.         $condition  =   $this->parseCondition($tag['condition']);
  172.         $parseStr   =   '<?php elseif('.$condition.'): ?>';
  173.         return $parseStr;
  174.     }

  175.     /**
  176.      * else标签解析
  177.      * @access public
  178.      * @param string $attr 标签属性
  179.      * @return string
  180.      */
  181.     public function _else($attr) {
  182.         $parseStr = '<?php else: ?>';
  183.         return $parseStr;
  184.     }

  185.     /**
  186.      * switch标签解析
  187.      * 格式:
  188.      * <switch name="a.name" >
  189.      * <case value="1" break="false">1</case>
  190.      * <case value="2" >2</case>
  191.      * <default />other
  192.      * </switch>
  193.      * @access public
  194.      * @param string $attr 标签属性
  195.      * @param string $content  标签内容
  196.      * @return string
  197.      */
  198.     public function _switch($attr,$content) {
  199.         $tag        =   $this->parseXmlAttr($attr,'switch');
  200.         $name       =   $tag['name'];
  201.         $varArray   =   explode('|',$name);
  202.         $name       =   array_shift($varArray);
  203.         $name       =   $this->autoBuildVar($name);
  204.         if(count($varArray)>0)
  205.             $name   =   $this->tpl->parseVarFunction($name,$varArray);
  206.         $parseStr   =   '<?php switch('.$name.'): ?>'.$content.'<?php endswitch;?>';
  207.         return $parseStr;
  208.     }

  209.     /**
  210.      * case标签解析 需要配合switch才有效
  211.      * @access public
  212.      * @param string $attr 标签属性
  213.      * @param string $content  标签内容
  214.      * @return string
  215.      */
  216.     public function _case($attr,$content) {
  217.         $tag    = $this->parseXmlAttr($attr,'case');
  218.         $value  = $tag['value'];
  219.         if('$' == substr($value,0,1)) {
  220.             $varArray   =   explode('|',$value);
  221.             $value        =    array_shift($varArray);
  222.             $value      =   $this->autoBuildVar(substr($value,1));
  223.             if(count($varArray)>0)
  224.                 $value  =   $this->tpl->parseVarFunction($value,$varArray);
  225.             $value      =   'case '.$value.': ';
  226.         }elseif(strpos($value,'|')){
  227.             $values     =   explode('|',$value);
  228.             $value      =   '';
  229.             foreach ($values as $val){
  230.                 $value   .=  'case "'.addslashes($val).'": ';
  231.             }
  232.         }else{
  233.             $value    =    'case "'.$value.'": ';
  234.         }
  235.         $parseStr = '<?php '.$value.' ?>'.$content;
  236.         $isBreak  = isset($tag['break']) ? $tag['break'] : '';
  237.         if('' ==$isBreak || $isBreak) {
  238.             $parseStr .= '<?php break;?>';
  239.         }
  240.         return $parseStr;
  241.     }

  242.     /**
  243.      * default标签解析 需要配合switch才有效
  244.      * 使用: <default />ddfdf
  245.      * @access public
  246.      * @param string $attr 标签属性
  247.      * @param string $content  标签内容
  248.      * @return string
  249.      */
  250.     public function _default($attr) {
  251.         $parseStr = '<?php default: ?>';
  252.         return $parseStr;
  253.     }

  254.     /**
  255.      * compare标签解析
  256.      * 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq
  257.      * 格式: <compare name="" type="eq" value="" >content</compare>
  258.      * @access public
  259.      * @param string $attr 标签属性
  260.      * @param string $content  标签内容
  261.      * @return string
  262.      */
  263.     public function _compare($attr,$content,$type='eq') {
  264.         $tag        =   $this->parseXmlAttr($attr,'compare');
  265.         $name       =   $tag['name'];
  266.         $value      =   $tag['value'];
  267.         $type       =   isset($tag['type'])?$tag['type']:$type;
  268.         $type       =   $this->parseCondition(' '.$type.' ');
  269.         $varArray   =   explode('|',$name);
  270.         $name       =   array_shift($varArray);
  271.         $name       =   $this->autoBuildVar($name);
  272.         if(count($varArray)>0)
  273.             $name = $this->tpl->parseVarFunction($name,$varArray);
  274.         if('$' == substr($value,0,1)) {
  275.             $value  =  $this->autoBuildVar(substr($value,1));
  276.         }else {
  277.             $value  =   '"'.$value.'"';
  278.         }
  279.         $parseStr   =   '<?php if(('.$name.') '.$type.' '.$value.'): ?>'.$content.'<?php endif; ?>';
  280.         return $parseStr;
  281.     }

  282.     public function _eq($attr,$content) {
  283.         return $this->_compare($attr,$content,'eq');
  284.     }

  285.     public function _equal($attr,$content) {
  286.         return $this->_compare($attr,$content,'eq');
  287.     }

  288.     public function _neq($attr,$content) {
  289.         return $this->_compare($attr,$content,'neq');
  290.     }

  291.     public function _notequal($attr,$content) {
  292.         return $this->_compare($attr,$content,'neq');
  293.     }

  294.     public function _gt($attr,$content) {
  295.         return $this->_compare($attr,$content,'gt');
  296.     }

  297.     public function _lt($attr,$content) {
  298.         return $this->_compare($attr,$content,'lt');
  299.     }

  300.     public function _egt($attr,$content) {
  301.         return $this->_compare($attr,$content,'egt');
  302.     }

  303.     public function _elt($attr,$content) {
  304.         return $this->_compare($attr,$content,'elt');
  305.     }

  306.     public function _heq($attr,$content) {
  307.         return $this->_compare($attr,$content,'heq');
  308.     }

  309.     public function _nheq($attr,$content) {
  310.         return $this->_compare($attr,$content,'nheq');
  311.     }

  312.     /**
  313.      * range标签解析
  314.      * 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外
  315.      * 格式: <range name="var|function"  value="val" type='in|notin' >content</range>
  316.      * example: <range name="a"  value="1,2,3" type='in' >content</range>
  317.      * @access public
  318.      * @param string $attr 标签属性
  319.      * @param string $content  标签内容
  320.      * @param string $type  比较类型
  321.      * @return string
  322.      */
  323.     public function _range($attr,$content,$type='in') {
  324.         $tag        =   $this->parseXmlAttr($attr,'range');
  325.         $name       =   $tag['name'];
  326.         $value      =   $tag['value'];
  327.         $varArray   =   explode('|',$name);
  328.         $name       =   array_shift($varArray);
  329.         $name       =   $this->autoBuildVar($name);
  330.         if(count($varArray)>0)
  331.             $name   =   $this->tpl->parseVarFunction($name,$varArray);

  332.         $type       =   isset($tag['type'])?$tag['type']:$type;

  333.         if('$' == substr($value,0,1)) {
  334.             $value  =   $this->autoBuildVar(substr($value,1));
  335.             $str    =   'is_array('.$value.')?'.$value.':explode(\',\','.$value.')';
  336.         }else{
  337.             $value  =   '"'.$value.'"';
  338.             $str    =   'explode(\',\','.$value.')';
  339.         }
  340.         if($type=='between') {
  341.             $parseStr = '<?php $_RANGE_VAR_='.$str.';if('.$name.'>= $_RANGE_VAR_[0] && '.$name.'<= $_RANGE_VAR_[1]):?>'.$content.'<?php endif; ?>';
  342.         }elseif($type=='notbetween'){
  343.             $parseStr = '<?php $_RANGE_VAR_='.$str.';if('.$name.'<$_RANGE_VAR_[0] || '.$name.'>$_RANGE_VAR_[1]):?>'.$content.'<?php endif; ?>';
  344.         }else{
  345.             $fun        =  ($type == 'in')? 'in_array'    :   '!in_array';
  346.             $parseStr   = '<?php if('.$fun.'(('.$name.'), '.$str.')): ?>'.$content.'<?php endif; ?>';
  347.         }
  348.         return $parseStr;
  349.     }

  350.     // range标签的别名 用于in判断
  351.     public function _in($attr,$content) {
  352.         return $this->_range($attr,$content,'in');
  353.     }

  354.     // range标签的别名 用于notin判断
  355.     public function _notin($attr,$content) {
  356.         return $this->_range($attr,$content,'notin');
  357.     }

  358.     public function _between($attr,$content){
  359.         return $this->_range($attr,$content,'between');
  360.     }

  361.     public function _notbetween($attr,$content){
  362.         return $this->_range($attr,$content,'notbetween');
  363.     }

  364.     /**
  365.      * present标签解析
  366.      * 如果某个变量已经设置 则输出内容
  367.      * 格式: <present name="" >content</present>
  368.      * @access public
  369.      * @param string $attr 标签属性
  370.      * @param string $content  标签内容
  371.      * @return string
  372.      */
  373.     public function _present($attr,$content) {
  374.         $tag        =   $this->parseXmlAttr($attr,'present');
  375.         $name       =   $tag['name'];
  376.         $name       =   $this->autoBuildVar($name);
  377.         $parseStr   =   '<?php if(isset('.$name.')): ?>'.$content.'<?php endif; ?>';
  378.         return $parseStr;
  379.     }

  380.     /**
  381.      * notpresent标签解析
  382.      * 如果某个变量没有设置,则输出内容
  383.      * 格式: <notpresent name="" >content</notpresent>
  384.      * @access public
  385.      * @param string $attr 标签属性
  386.      * @param string $content  标签内容
  387.      * @return string
  388.      */
  389.     public function _notpresent($attr,$content) {
  390.         $tag        =   $this->parseXmlAttr($attr,'notpresent');
  391.         $name       =   $tag['name'];
  392.         $name       =   $this->autoBuildVar($name);
  393.         $parseStr   =   '<?php if(!isset('.$name.')): ?>'.$content.'<?php endif; ?>';
  394.         return $parseStr;
  395.     }

  396.     /**
  397.      * empty标签解析
  398.      * 如果某个变量为empty 则输出内容
  399.      * 格式: <empty name="" >content</empty>
  400.      * @access public
  401.      * @param string $attr 标签属性
  402.      * @param string $content  标签内容
  403.      * @return string
  404.      */
  405.     public function _empty($attr,$content) {
  406.         $tag        =   $this->parseXmlAttr($attr,'empty');
  407.         $name       =   $tag['name'];
  408.         $name       =   $this->autoBuildVar($name);
  409.         $parseStr   =   '<?php if(empty('.$name.')): ?>'.$content.'<?php endif; ?>';
  410.         return $parseStr;
  411.     }

  412.     public function _notempty($attr,$content) {
  413.         $tag        =   $this->parseXmlAttr($attr,'notempty');
  414.         $name       =   $tag['name'];
  415.         $name       =   $this->autoBuildVar($name);
  416.         $parseStr   =   '<?php if(!empty('.$name.')): ?>'.$content.'<?php endif; ?>';
  417.         return $parseStr;
  418.     }

  419.     /**
  420.      * 判断是否已经定义了该常量
  421.      * <defined name='TXT'>已定义</defined>
  422.      * @param <type> $attr
  423.      * @param <type> $content
  424.      * @return string
  425.      */
  426.     public function _defined($attr,$content) {
  427.         $tag        =   $this->parseXmlAttr($attr,'defined');
  428.         $name       =   $tag['name'];
  429.         $parseStr   =   '<?php if(defined("'.$name.'")): ?>'.$content.'<?php endif; ?>';
  430.         return $parseStr;
  431.     }

  432.     public function _notdefined($attr,$content) {
  433.         $tag        =   $this->parseXmlAttr($attr,'_notdefined');
  434.         $name       =   $tag['name'];
  435.         $parseStr   =   '<?php if(!defined("'.$name.'")): ?>'.$content.'<?php endif; ?>';
  436.         return $parseStr;
  437.     }

  438.     /**
  439.      * import 标签解析 <import file="Js.Base" /> 
  440.      * <import file="Css.Base" type="css" />
  441.      * @access public
  442.      * @param string $attr 标签属性
  443.      * @param string $content  标签内容
  444.      * @param boolean $isFile  是否文件方式
  445.      * @param string $type  类型
  446.      * @return string
  447.      */
  448.     public function _import($attr,$content,$isFile=false,$type='') {
  449.         $tag        =   $this->parseXmlAttr($attr,'import');
  450.         $file       =   isset($tag['file'])?$tag['file']:$tag['href'];
  451.         $parseStr   =   '';
  452.         $endStr     =   '';
  453.         // 判断是否存在加载条件 允许使用函数判断(默认为isset)
  454.         if (isset($tag['value'])) {
  455.             $varArray  =    explode('|',$tag['value']);
  456.             $name      =    array_shift($varArray);
  457.             $name      =    $this->autoBuildVar($name);
  458.             if (!empty($varArray))
  459.                 $name  =    $this->tpl->parseVarFunction($name,$varArray);
  460.             else
  461.                 $name  =    'isset('.$name.')';
  462.             $parseStr .=    '<?php if('.$name.'): ?>';
  463.             $endStr    =    '<?php endif; ?>';
  464.         }
  465.         if($isFile) {
  466.             // 根据文件名后缀自动识别
  467.             $type  = $type?$type:(!empty($tag['type'])?strtolower($tag['type']):null);
  468.             // 文件方式导入
  469.             $array =  explode(',',$file);
  470.             foreach ($array as $val){
  471.                 if (!$type || isset($reset)) {
  472.                     $type = $reset = strtolower(substr(strrchr($val, '.'),1));
  473.                 }
  474.                 switch($type) {
  475.                 case 'js':
  476.                     $parseStr .= '<script type="text/javascript" src="'.$val.'"></script>';
  477.                     break;
  478.                 case 'css':
  479.                     $parseStr .= '<link rel="stylesheet" type="text/css" href="'.$val.'" />';
  480.                     break;
  481.                 case 'php':
  482.                     $parseStr .= '<?php require_cache("'.$val.'"); ?>';
  483.                     break;
  484.                 }
  485.             }
  486.         }else{
  487.             // 命名空间导入模式 默认是js
  488.             $type       =   $type?$type:(!empty($tag['type'])?strtolower($tag['type']):'js');
  489.             $basepath   =   !empty($tag['basepath'])?$tag['basepath']:__ROOT__.'/Public';
  490.             // 命名空间方式导入外部文件
  491.             $array      =   explode(',',$file);
  492.             foreach ($array as $val){
  493.                 list($val,$version) =   explode('?',$val);
  494.                 switch($type) {
  495.                 case 'js':
  496.                     $parseStr .= '<script type="text/javascript" src="'.$basepath.'/'.str_replace(array('.','#'), array('/','.'),$val).'.js'.($version?'?'.$version:'').'"></script>';
  497.                     break;
  498.                 case 'css':
  499.                     $parseStr .= '<link rel="stylesheet" type="text/css" href="'.$basepath.'/'.str_replace(array('.','#'), array('/','.'),$val).'.css'.($version?'?'.$version:'').'" />';
  500.                     break;
  501.                 case 'php':
  502.                     $parseStr .= '<?php import("'.$val.'"); ?>';
  503.                     break;
  504.                 }
  505.             }
  506.         }
  507.         return $parseStr.$endStr;
  508.     }

  509.     // import别名 采用文件方式加载(要使用命名空间必须用import) 例如 <load file="__PUBLIC__/Js/Base.js" />
  510.     public function _load($attr,$content) {
  511.         return $this->_import($attr,$content,true);
  512.     }

  513.     // import别名使用 导入css文件 <css file="__PUBLIC__/Css/Base.css" />
  514.     public function _css($attr,$content) {
  515.         return $this->_import($attr,$content,true,'css');
  516.     }

  517.     // import别名使用 导入js文件 <js file="__PUBLIC__/Js/Base.js" />
  518.     public function _js($attr,$content) {
  519.         return $this->_import($attr,$content,true,'js');
  520.     }

  521.     /**
  522.      * assign标签解析
  523.      * 在模板中给某个变量赋值 支持变量赋值
  524.      * 格式: <assign name="" value="" />
  525.      * @access public
  526.      * @param string $attr 标签属性
  527.      * @param string $content  标签内容
  528.      * @return string
  529.      */
  530.     public function _assign($attr,$content) {
  531.         $tag        =   $this->parseXmlAttr($attr,'assign');
  532.         $name       =   $this->autoBuildVar($tag['name']);
  533.         if('$'==substr($tag['value'],0,1)) {
  534.             $value  =   $this->autoBuildVar(substr($tag['value'],1));
  535.         }else{
  536.             $value  =   '\''.$tag['value']. '\'';
  537.         }
  538.         $parseStr   =   '<?php '.$name.' = '.$value.'; ?>';
  539.         return $parseStr;
  540.     }

  541.     /**
  542.      * define标签解析
  543.      * 在模板中定义常量 支持变量赋值
  544.      * 格式: <define name="" value="" />
  545.      * @access public
  546.      * @param string $attr 标签属性
  547.      * @param string $content  标签内容
  548.      * @return string
  549.      */
  550.     public function _define($attr,$content) {
  551.         $tag        =   $this->parseXmlAttr($attr,'define');
  552.         $name       =   '\''.$tag['name']. '\'';
  553.         if('$'==substr($tag['value'],0,1)) {
  554.             $value  =   $this->autoBuildVar(substr($tag['value'],1));
  555.         }else{
  556.             $value  =   '\''.$tag['value']. '\'';
  557.         }
  558.         $parseStr   =   '<?php define('.$name.', '.$value.'); ?>';
  559.         return $parseStr;
  560.     }
  561.     
  562.     /**
  563.      * for标签解析
  564.      * 格式: <for start="" end="" comparison="" step="" name="" />
  565.      * @access public
  566.      * @param string $attr 标签属性
  567.      * @param string $content  标签内容
  568.      * @return string
  569.      */
  570.     public function _for($attr, $content){
  571.         //设置默认值
  572.         $start         = 0;
  573.         $end           = 0;
  574.         $step         = 1;
  575.         $comparison = 'lt';
  576.         $name        = 'i';
  577.         $rand       = rand(); //添加随机数,防止嵌套变量冲突
  578.         //获取属性
  579.         foreach ($this->parseXmlAttr($attr, 'for') as $key => $value){
  580.             $value = trim($value);
  581.             if(':'==substr($value,0,1))
  582.                 $value = substr($value,1);
  583.             elseif('$'==substr($value,0,1))
  584.                 $value = $this->autoBuildVar(substr($value,1));
  585.             switch ($key){
  586.                 case 'start':   
  587.                     $start      = $value; break;
  588.                 case 'end' :    
  589.                     $end        = $value; break;
  590.                 case 'step':    
  591.                     $step       = $value; break;
  592.                 case 'comparison':
  593.                     $comparison = $value; break;
  594.                 case 'name':
  595.                     $name       = $value; break;
  596.             }
  597.         }
  598.         
  599.         $parseStr   = '<?php $__FOR_START_'.$rand.'__='.$start.';$__FOR_END_'.$rand.'__='.$end.';';
  600.         $parseStr  .= 'for($'.$name.'=$__FOR_START_'.$rand.'__;'.$this->parseCondition('$'.$name.' '.$comparison.' $__FOR_END_'.$rand.'__').';$'.$name.'+='.$step.'){ ?>';
  601.         $parseStr  .= $content;
  602.         $parseStr  .= '<?php } ?>';
  603.         return $parseStr;
  604.     }

  605.     }