[李景山php]thinkphp核心源码注释|Cx.class.php

来源:互联网 发布:win32编程还有用吗 编辑:程序博客网 时间:2024/05/29 17:55
<?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]// +----------------------------------------------------------------------// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +----------------------------------------------------------------------namespace Think\Template\TagLib;use Think\Template\TagLib;/** * CX标签库解析类 * 这里的 那个 继承了 */class Cx extends TagLib {    // 标签定义    protected $tags   =  array(        // 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次        'php'       =>  array(),        // 这里 什么都没了        'volist'    =>  array('attr'=>'name,id,offset,length,key,mod','level'=>3,'alias'=>'iterate'),        // 里面        'foreach'   =>  array('attr'=>'name,item,key','level'=>3),        'if'        =>  array('attr'=>'condition','level'=>2),        'elseif'    =>  array('attr'=>'condition','close'=>0),        'else'      =>  array('attr'=>'','close'=>0),        'switch'    =>  array('attr'=>'name','level'=>2),        'case'      =>  array('attr'=>'value,break'),        'default'   =>  array('attr'=>'','close'=>0),        //        'compare'   =>  array('attr'=>'name,value,type','level'=>3,'alias'=>'eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq'),        'range'     =>  array('attr'=>'name,value,type','level'=>3,'alias'=>'in,notin,between,notbetween'),        'empty'     =>  array('attr'=>'name','level'=>3),        'notempty'  =>  array('attr'=>'name','level'=>3),        'present'   =>  array('attr'=>'name','level'=>3),        'notpresent'=>  array('attr'=>'name','level'=>3),        'defined'   =>  array('attr'=>'name','level'=>3),        'notdefined'=>  array('attr'=>'name','level'=>3),        'import'    =>  array('attr'=>'file,href,type,value,basepath','close'=>0,'alias'=>'load,css,js'),        'assign'    =>  array('attr'=>'name,value','close'=>0),        'define'    =>  array('attr'=>'name,value','close'=>0),        'for'       =>  array('attr'=>'start,end,name,comparison,step', 'level'=>3),        );// 导入 全部支持的标签在这里了,    // 分了: attr level close alias    /**     * php标签解析     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     * 这里的 那个     */    public function _php($tag,$content) {        $parseStr = '<?php '.$content.' ?>';        return $parseStr;    }// 这里的 那个 php 标签    /**     * volist标签解析 循环输出数据集     * 格式:     * <volist name="userList" id="user" empty="" >     * {user.username}     * {user.email}     * </volist>     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string|void     */    public function _volist($tag,$content) {        $name  =    $tag['name'];// 找到里面的那个 $name        $id    =    $tag['id']; // 获取了 id        $empty =    isset($tag['empty'])?$tag['empty']:'';// 这里的 为空        $key   =    !empty($tag['key'])?$tag['key']:'i';// key i        $mod   =    isset($tag['mod'])?$tag['mod']:'2';// mod        // 允许使用函数设定数据集 <volist name=":fun('arg')" id="vo">{$vo.name}</volist>        // 我去 这个还有这样的 东西        $parseStr   =  '<?php '; // 保存开始了        if(0===strpos($name,':')) {            $parseStr   .= '$_result='.substr($name,1).';';// 如果是函数了            $name   = '$_result';// name 里面的 那个  直接是函数开始了        }else{            $name   = $this->autoBuildVar($name); // 解析 里面的标签,还是 那些通用的 标签了        }// 准备参数,准备 变量        $parseStr  .=  'if(is_array('.$name.')): $'.$key.' = 0;'; // 如果是数组呢        if(isset($tag['length']) && '' !=$tag['length'] ) { // 这里的 那个            // array_slice(array,start,length,preserve)            $parseStr  .= ' $__LIST__ = array_slice('.$name.','.$tag['offset'].','.$tag['length'].',true);';        }elseif(isset($tag['offset'])  && '' !=$tag['offset']){            $parseStr  .= ' $__LIST__ = array_slice('.$name.','.$tag['offset'].',null,true);';        }else{            $parseStr .= ' $__LIST__ = '.$name.';';        }// 把这里的那个 真实的数据弄出来        $parseStr .= 'if( count($__LIST__)==0 ) : echo "'.$empty.'" ;';        $parseStr .= 'else: ';        $parseStr .= 'foreach($__LIST__ as $key=>$'.$id.'): ';        $parseStr .= '$mod = ($'.$key.' % '.$mod.' );';        $parseStr .= '++$'.$key.';?>';        $parseStr .= $this->tpl->parse($content);        $parseStr .= '<?php endforeach; endif; else: echo "'.$empty.'" ;endif; ?>';        if(!empty($parseStr)) {            return $parseStr;        }        return ;    }// 发现了 里面的 东西了 就是 volist 里面的    /**     * foreach标签解析 循环输出数据集     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string|void     */    public function _foreach($tag,$content) {        $name       =   $tag['name'];        $item       =   $tag['item'];        $key        =   !empty($tag['key'])?$tag['key']:'key';        $name       =   $this->autoBuildVar($name);        $parseStr   =   '<?php if(is_array('.$name.')): foreach('.$name.' as $'.$key.'=>$'.$item.'): ?>';        $parseStr  .=   $this->tpl->parse($content);        $parseStr  .=   '<?php endforeach; endif; ?>';        if(!empty($parseStr)) {            return $parseStr;        }        return ;    }// 这里的 不错呢    /**     * if标签解析     * 格式:     * <if condition=" $a eq 1" >     * <elseif condition="$a eq 2" />     * <else />     * </if>     * 表达式支持 eq neq gt egt lt elt == > >= < <= or and || &&     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _if($tag,$content) {        $condition  =   $this->parseCondition($tag['condition']);        $parseStr   =   '<?php if('.$condition.'): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }// 这里的 解析了    /**     * else标签解析     * 格式:见if标签     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _elseif($tag,$content) {        $condition  =   $this->parseCondition($tag['condition']);        $parseStr   =   '<?php elseif('.$condition.'): ?>';        return $parseStr;    }// 解析了 else 里面的 东西    /**     * else标签解析     * @access public     * @param array $tag 标签属性     * @return string     */    public function _else($tag) {        $parseStr = '<?php else: ?>';        return $parseStr;    }// 这里的 那个    /**     * switch标签解析     * 格式:     * <switch name="a.name" >     * <case value="1" break="false">1</case>     * <case value="2" >2</case>     * <default />other     * </switch>     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _switch($tag,$content) {        $name       =   $tag['name'];        $varArray   =   explode('|',$name);        $name       =   array_shift($varArray);        $name       =   $this->autoBuildVar($name);        if(count($varArray)>0)            $name   =   $this->tpl->parseVarFunction($name,$varArray);        $parseStr   =   '<?php switch('.$name.'): ?>'.$content.'<?php endswitch;?>';        return $parseStr;    }// 这里的 东西 不错了    /**     * case标签解析 需要配合switch才有效     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _case($tag,$content) {        $value  = $tag['value'];        if('$' == substr($value,0,1)) {            $varArray   =   explode('|',$value);            $value    =array_shift($varArray);            $value      =   $this->autoBuildVar(substr($value,1));            if(count($varArray)>0)                $value  =   $this->tpl->parseVarFunction($value,$varArray);            $value      =   'case '.$value.': ';        }elseif(strpos($value,'|')){            $values     =   explode('|',$value);            $value      =   '';            foreach ($values as $val){                $value   .=  'case "'.addslashes($val).'": ';            }        }else{            $value='case "'.$value.'": ';        }        $parseStr = '<?php '.$value.' ?>'.$content;        $isBreak  = isset($tag['break']) ? $tag['break'] : '';        if('' ==$isBreak || $isBreak) {            $parseStr .= '<?php break;?>';        }        return $parseStr;    }// 这里的 代码都是case 的转码了    /**     * default标签解析 需要配合switch才有效     * 使用: <default />ddfdf     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _default($tag) {        $parseStr = '<?php default: ?>';        return $parseStr;    }// 这里 那个 配合 switch 里面的    /**     * compare标签解析     * 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq     * 格式: <compare name="" type="eq" value="" >content</compare>     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _compare($tag,$content,$type='eq') {        $name       =   $tag['name'];        $value      =   $tag['value'];        $type       =   isset($tag['type'])?$tag['type']:$type;        $type       =   $this->parseCondition(' '.$type.' ');        $varArray   =   explode('|',$name);        $name       =   array_shift($varArray);        $name       =   $this->autoBuildVar($name);        if(count($varArray)>0)            $name = $this->tpl->parseVarFunction($name,$varArray);        if('$' == substr($value,0,1)) {            $value  =  $this->autoBuildVar(substr($value,1));        }else {            $value  =   '"'.$value.'"';        }        $parseStr   =   '<?php if(('.$name.') '.$type.' '.$value.'): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }// 还不如把他解析了 里面 那个    public function _eq($tag,$content) {        return $this->_compare($tag,$content,'eq');    }    public function _equal($tag,$content) {        return $this->_compare($tag,$content,'eq');    }    public function _neq($tag,$content) {        return $this->_compare($tag,$content,'neq');    }    public function _notequal($tag,$content) {        return $this->_compare($tag,$content,'neq');    }    public function _gt($tag,$content) {        return $this->_compare($tag,$content,'gt');    }    public function _lt($tag,$content) {        return $this->_compare($tag,$content,'lt');    }    public function _egt($tag,$content) {        return $this->_compare($tag,$content,'egt');    }    public function _elt($tag,$content) {        return $this->_compare($tag,$content,'elt');    }    public function _heq($tag,$content) {        return $this->_compare($tag,$content,'heq');    }    public function _nheq($tag,$content) {        return $this->_compare($tag,$content,'nheq');    }    // 这里的 特殊的 代码    /**     * range标签解析     * 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外     * 格式: <range name="var|function"  value="val" type='in|notin' >content</range>     * example: <range name="a"  value="1,2,3" type='in' >content</range>     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @param string $type  比较类型     * @return string     */    public function _range($tag,$content,$type='in') {        $name       =   $tag['name'];        $value      =   $tag['value'];        $varArray   =   explode('|',$name);        $name       =   array_shift($varArray);        $name       =   $this->autoBuildVar($name);        if(count($varArray)>0)            $name   =   $this->tpl->parseVarFunction($name,$varArray);        $type       =   isset($tag['type'])?$tag['type']:$type;        if('$' == substr($value,0,1)) {            $value  =   $this->autoBuildVar(substr($value,1));            $str    =   'is_array('.$value.')?'.$value.':explode(\',\','.$value.')';        }else{            $value  =   '"'.$value.'"';            $str    =   'explode(\',\','.$value.')';        }        if($type=='between') {            $parseStr = '<?php $_RANGE_VAR_='.$str.';if('.$name.'>= $_RANGE_VAR_[0] && '.$name.'<= $_RANGE_VAR_[1]):?>'.$content.'<?php endif; ?>';        }elseif($type=='notbetween'){            $parseStr = '<?php $_RANGE_VAR_='.$str.';if('.$name.'<$_RANGE_VAR_[0] || '.$name.'>$_RANGE_VAR_[1]):?>'.$content.'<?php endif; ?>';        }else{            $fun        =  ($type == 'in')? 'in_array'    :   '!in_array';            $parseStr   = '<?php if('.$fun.'(('.$name.'), '.$str.')): ?>'.$content.'<?php endif; ?>';        }        return $parseStr;    } // 这种里面的代码 是否都可以替换成为 那个    // range标签的别名 用于in判断    public function _in($tag,$content) {        return $this->_range($tag,$content,'in');    }    // range标签的别名 用于notin判断    public function _notin($tag,$content) {        return $this->_range($tag,$content,'notin');    }    public function _between($tag,$content){        return $this->_range($tag,$content,'between');    }    public function _notbetween($tag,$content){        return $this->_range($tag,$content,'notbetween');    }    // 别名 不错啊    /**     * present标签解析     * 如果某个变量已经设置 则输出内容     * 格式: <present name="" >content</present>     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _present($tag,$content) {        $name       =   $tag['name'];        $name       =   $this->autoBuildVar($name);        $parseStr   =   '<?php if(isset('.$name.')): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }// 这里的那个 是    /**     * notpresent标签解析     * 如果某个变量没有设置,则输出内容     * 格式: <notpresent name="" >content</notpresent>     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _notpresent($tag,$content) {        $name       =   $tag['name'];        $name       =   $this->autoBuildVar($name);        $parseStr   =   '<?php if(!isset('.$name.')): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }// 这里的标签了    /**     * empty标签解析     * 如果某个变量为empty 则输出内容     * 格式: <empty name="" >content</empty>     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _empty($tag,$content) {        $name       =   $tag['name'];        $name       =   $this->autoBuildVar($name);        $parseStr   =   '<?php if(empty('.$name.')): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }    public function _notempty($tag,$content) {        $name       =   $tag['name'];        $name       =   $this->autoBuildVar($name);        $parseStr   =   '<?php if(!empty('.$name.')): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }// 这里的那个    /**     * 判断是否已经定义了该常量     * <defined name='TXT'>已定义</defined>     * @param <type> $attr     * @param <type> $content     * @return string     */    public function _defined($tag,$content) {        $name       =   $tag['name'];        $parseStr   =   '<?php if(defined("'.$name.'")): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }// 都是转成 if    public function _notdefined($tag,$content) {        $name       =   $tag['name'];        $parseStr   =   '<?php if(!defined("'.$name.'")): ?>'.$content.'<?php endif; ?>';        return $parseStr;    }// 都是 转成    /**     * import 标签解析 <import file="Js.Base" />      * <import file="Css.Base" type="css" />     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @param boolean $isFile  是否文件方式     * @param string $type  类型     * @return string     */    public function _import($tag,$content,$isFile=false,$type='') {        $file       =   isset($tag['file'])?$tag['file']:$tag['href'];        $parseStr   =   '';        $endStr     =   '';        // 判断是否存在加载条件 允许使用函数判断(默认为isset)        if (isset($tag['value'])) {            $varArray  =    explode('|',$tag['value']);            $name      =    array_shift($varArray);            $name      =    $this->autoBuildVar($name);            if (!empty($varArray))                $name  =    $this->tpl->parseVarFunction($name,$varArray);            else                $name  =    'isset('.$name.')';            $parseStr .=    '<?php if('.$name.'): ?>';            $endStr    =    '<?php endif; ?>';        }        if($isFile) {            // 根据文件名后缀自动识别            $type  = $type?$type:(!empty($tag['type'])?strtolower($tag['type']):null);            // 文件方式导入            $array =  explode(',',$file);            foreach ($array as $val){                if (!$type || isset($reset)) {                    $type = $reset = strtolower(substr(strrchr($val, '.'),1));                }                switch($type) {                case 'js':                    $parseStr .= '<script type="text/javascript" src="'.$val.'"></script>';                    break;                case 'css':                    $parseStr .= '<link rel="stylesheet" type="text/css" href="'.$val.'" />';                    break;                case 'php':                    $parseStr .= '<?php require_cache("'.$val.'"); ?>';                    break;                }            }        }else{            // 命名空间导入模式 默认是js            $type       =   $type?$type:(!empty($tag['type'])?strtolower($tag['type']):'js');            $basepath   =   !empty($tag['basepath'])?$tag['basepath']:__ROOT__.'/Public';            // 命名空间方式导入外部文件            $array      =   explode(',',$file);            foreach ($array as $val){                if(strpos ($val, '?')) {                    list($val,$version) =   explode('?',$val);                } else {                    $version = '';                }                switch($type) {                case 'js':                    $parseStr .= '<script type="text/javascript" src="'.$basepath.'/'.str_replace(array('.','#'), array('/','.'),$val).'.js'.($version?'?'.$version:'').'"></script>';                    break;                case 'css':                    $parseStr .= '<link rel="stylesheet" type="text/css" href="'.$basepath.'/'.str_replace(array('.','#'), array('/','.'),$val).'.css'.($version?'?'.$version:'').'" />';                    break;                case 'php':                    $parseStr .= '<?php import("'.$val.'"); ?>';                    break;                }            }        }        return $parseStr.$endStr;    }// 这里 是可以 进入那个 包含 什么各种各样的文件 type 里面的产品了    // import别名 采用文件方式加载(要使用命名空间必须用import) 例如 <load file="__PUBLIC__/Js/Base.js" />    public function _load($tag,$content) {        return $this->_import($tag,$content,true);    }    // import别名使用 导入css文件 <css file="__PUBLIC__/Css/Base.css" />    public function _css($tag,$content) {        return $this->_import($tag,$content,true,'css');    }    // import别名使用 导入js文件 <js file="__PUBLIC__/Js/Base.js" />    public function _js($tag,$content) {        return $this->_import($tag,$content,true,'js');    }    /**     * assign标签解析     * 在模板中给某个变量赋值 支持变量赋值     * 格式: <assign name="" value="" />     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _assign($tag,$content) {        $name       =   $this->autoBuildVar($tag['name']);        if('$'==substr($tag['value'],0,1)) {            $value  =   $this->autoBuildVar(substr($tag['value'],1));        }else{            $value  =   '\''.$tag['value']. '\'';        }        $parseStr   =   '<?php '.$name.' = '.$value.'; ?>';        return $parseStr;    }// assign 就是复制过来了,找到原型了    /**     * define标签解析     * 在模板中定义常量 支持变量赋值     * 格式: <define name="" value="" />     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _define($tag,$content) {        $name       =   '\''.$tag['name']. '\'';        if('$'==substr($tag['value'],0,1)) {            $value  =   $this->autoBuildVar(substr($tag['value'],1));        }else{            $value  =   '\''.$tag['value']. '\'';        }        $parseStr   =   '<?php define('.$name.', '.$value.'); ?>';        return $parseStr;    }// 找到了 define 里面的定义了    /**     * for标签解析     * 格式: <for start="" end="" comparison="" step="" name="" />     * @access public     * @param array $tag 标签属性     * @param string $content  标签内容     * @return string     */    public function _for($tag, $content){        //设置默认值        $start         = 0;        $end           = 0;        $step      = 1;        $comparison = 'lt';        $name      = 'i';        $rand       = rand(); //添加随机数,防止嵌套变量冲突        //获取属性        foreach ($tag as $key => $value){            $value = trim($value);            if(':'==substr($value,0,1))                $value = substr($value,1);            elseif('$'==substr($value,0,1))                $value = $this->autoBuildVar(substr($value,1));            switch ($key){                case 'start':                       $start      = $value; break;                case 'end' :                        $end        = $value; break;                case 'step':                        $step       = $value; break;                case 'comparison':                    $comparison = $value; break;                case 'name':                    $name       = $value; break;            }        }        $parseStr   = '<?php $__FOR_START_'.$rand.'__='.$start.';$__FOR_END_'.$rand.'__='.$end.';';        $parseStr  .= 'for($'.$name.'=$__FOR_START_'.$rand.'__;'.$this->parseCondition('$'.$name.' '.$comparison.' $__FOR_END_'.$rand.'__').';$'.$name.'+='.$step.'){ ?>';        $parseStr  .= $content;        $parseStr  .= '<?php } ?>';        return $parseStr;    }// for 标签专用}
0 0
原创粉丝点击