BVB Source Codes

The latest thinkphp v5.2 work order system Show Template.class.php Source code

Return Download The latest thinkphp v5.2 work order system: download Template.class.php Source code - Download The latest thinkphp v5.2 work order system Source code - Type:.php
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2014 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. namespace Think;
  12. /**
  13.  * ThinkPHP内置模板引擎类
  14.  * 支持XML标签和普通标签的模板解析
  15.  * 编译型模板引擎 支持动态缓存
  16.  */
  17. class  Template {
  18.  
  19.     // 模板页面中引入的标签库列表
  20.     protected   $tagLib          =   array();
  21.     // 当前模板文件
  22.     protected   $templateFile    =   '';
  23.     // 模板变量
  24.     public      $tVar            =   array();
  25.     public      $config          =   array();
  26.     private     $literal         =   array();
  27.     private     $block           =   array();
  28.  
  29.     /**
  30.      * 架构函数
  31.      * @access public
  32.      */
  33.     public function __construct(){
  34.         $this->config['cache_path']         =   C('CACHE_PATH');
  35.         $this->config['template_suffix']    =   C('TMPL_TEMPLATE_SUFFIX');
  36.         $this->config['cache_suffix']       =   C('TMPL_CACHFILE_SUFFIX');
  37.         $this->config['tmpl_cache']         =   C('TMPL_CACHE_ON');
  38.         $this->config['cache_time']         =   C('TMPL_CACHE_TIME');
  39.         $this->config['taglib_begin']       =   $this->stripPreg(C('TAGLIB_BEGIN'));
  40.         $this->config['taglib_end']         =   $this->stripPreg(C('TAGLIB_END'));
  41.         $this->config['tmpl_begin']         =   $this->stripPreg(C('TMPL_L_DELIM'));
  42.         $this->config['tmpl_end']           =   $this->stripPreg(C('TMPL_R_DELIM'));
  43.         $this->config['default_tmpl']       =   C('TEMPLATE_NAME');
  44.         $this->config['layout_item']        =   C('TMPL_LAYOUT_ITEM');
  45.     }
  46.  
  47.     private function stripPreg($str) {
  48.         return str_replace(
  49.             array('{','}','(',')','|','[',']','-','+','*','.','^','?'),
  50.             array('\{','\}','\(','\)','\|','\[','\]','\-','\+','\*','\.','\^','\?'),
  51.             $str);        
  52.     }
  53.  
  54.     // 模板变量获取和设置
  55.     public function get($name) {
  56.         if(isset($this->tVar[$name]))
  57.             return $this->tVar[$name];
  58.         else
  59.             return false;
  60.     }
  61.  
  62.     public function set($name,$value) {
  63.         $this->tVar[$name]= $value;
  64.     }
  65.  
  66.     /**
  67.      * 加载模板
  68.      * @access public
  69.      * @param string $templateFile 模板文件
  70.      * @param array  $templateVar 模板变量
  71.      * @param string $prefix 模板标识前缀
  72.      * @return void
  73.      */
  74.     public function fetch($templateFile,$templateVar,$prefix='') {
  75.         $this->tVar         =   $templateVar;
  76.         $templateCacheFile  =   $this->loadTemplate($templateFile,$prefix);
  77.         Storage::load($templateCacheFile,$this->tVar,null,'tpl');
  78.     }
  79.  
  80.     /**
  81.      * 加载主模板并缓存
  82.      * @access public
  83.      * @param string $templateFile 模板文件
  84.      * @param string $prefix 模板标识前缀
  85.      * @return string
  86.      * @throws ThinkExecption
  87.      */
  88.     public function loadTemplate ($templateFile,$prefix='') {
  89.         if(is_file($templateFile)) {
  90.             $this->templateFile    =  $templateFile;
  91.             // 读取模板文件内容
  92.             $tmplContent =  file_get_contents($templateFile);
  93.         }else{
  94.             $tmplContent =  $templateFile;
  95.         }
  96.          // 根据模版文件名定位缓存文件
  97.         $tmplCacheFile = $this->config['cache_path'].$prefix.md5($templateFile).$this->config['cache_suffix'];
  98.  
  99.         // 判断是否启用布局
  100.         if(C('LAYOUT_ON')) {
  101.             if(false !== strpos($tmplContent,'{__NOLAYOUT__}')) { // 可以单独定义不使用布局
  102.                 $tmplContent = str_replace('{__NOLAYOUT__}','',$tmplContent);
  103.             }else{ // 替换布局的主体内容
  104.                 $layoutFile  =  THEME_PATH.C('LAYOUT_NAME').$this->config['template_suffix'];
  105.                 // 检查布局文件
  106.                 if(!is_file($layoutFile)) {
  107.                     E(L('_TEMPLATE_NOT_EXIST_').':'.$layoutFile);
  108.                 }
  109.                 $tmplContent = str_replace($this->config['layout_item'],$tmplContent,file_get_contents($layoutFile));
  110.             }
  111.         }
  112.         // 编译模板内容
  113.         $tmplContent =  $this->compiler($tmplContent);
  114.         Storage::put($tmplCacheFile,trim($tmplContent),'tpl');
  115.         return $tmplCacheFile;
  116.     }
  117.  
  118.     /**
  119.      * 编译模板文件内容
  120.      * @access protected
  121.      * @param mixed $tmplContent 模板内容
  122.      * @return string
  123.      */
  124.     protected function compiler($tmplContent) {
  125.         //模板解析
  126.         $tmplContent =  $this->parse($tmplContent);
  127.         // 还原被替换的Literal标签
  128.         $tmplContent =  preg_replace_callback('/<!--###literal(\d+)###-->/is', array($this, 'restoreLiteral'), $tmplContent);
  129.         // 添加安全代码
  130.         $tmplContent =  '<?php if (!defined(\'THINK_PATH\')) exit();?>'.$tmplContent;
  131.         // 优化生成的php代码
  132.         $tmplContent = str_replace('?><?php','',$tmplContent);
  133.         // 模版编译过滤标签
  134.         Hook::listen('template_filter',$tmplContent);
  135.         return strip_whitespace($tmplContent);
  136.     }
  137.  
  138.     /**
  139.      * 模板解析入口
  140.      * 支持普通标签和TagLib解析 支持自定义标签库
  141.      * @access public
  142.      * @param string $content 要解析的模板内容
  143.      * @return string
  144.      */
  145.     public function parse($content) {
  146.         // 内容为空不解析
  147.         if(empty($content)) return '';
  148.         $begin      =   $this->config['taglib_begin'];
  149.         $end        =   $this->config['taglib_end'];
  150.         // 检查include语法
  151.         $content    =   $this->parseInclude($content);
  152.         // 检查PHP语法
  153.         $content    =   $this->parsePhp($content);
  154.         // 首先替换literal标签内容
  155.         $content    =   preg_replace_callback('/'.$begin.'literal'.$end.'(.*?)'.$begin.'\/literal'.$end.'/is', array($this, 'parseLiteral'),$content);
  156.  
  157.         // 获取需要引入的标签库列表
  158.         // 标签库只需要定义一次,允许引入多个一次
  159.         // 一般放在文件的最前面
  160.         // 格式:<taglib name="html,mytag..." />
  161.         // 当TAGLIB_LOAD配置为true时才会进行检测
  162.         if(C('TAGLIB_LOAD')) {
  163.             $this->getIncludeTagLib($content);
  164.             if(!empty($this->tagLib)) {
  165.                 // 对导入的TagLib进行解析
  166.                 foreach($this->tagLib as $tagLibName) {
  167.                     $this->parseTagLib($tagLibName,$content);
  168.                 }
  169.             }
  170.         }
  171.         // 预先加载的标签库 无需在每个模板中使用taglib标签加载 但必须使用标签库XML前缀
  172.         if(C('TAGLIB_PRE_LOAD')) {
  173.             $tagLibs =  explode(',',C('TAGLIB_PRE_LOAD'));
  174.             foreach ($tagLibs as $tag){
  175.                 $this->parseTagLib($tag,$content);
  176.             }
  177.         }
  178.         // 内置标签库 无需使用taglib标签导入就可以使用 并且不需使用标签库XML前缀
  179.         $tagLibs =  explode(',',C('TAGLIB_BUILD_IN'));
  180.         foreach ($tagLibs as $tag){
  181.             $this->parseTagLib($tag,$content,true);
  182.         }
  183.         //解析普通模板标签 {$tagName}
  184.         $content = preg_replace_callback('/('.$this->config['tmpl_begin'].')([^\d\w\s'.$this->config['tmpl_begin'].$this->config['tmpl_end'].'].+?)('.$this->config['tmpl_end'].')/is', array($this, 'parseTag'),$content);
  185.         return $content;
  186.     }
  187.  
  188.     // 检查PHP语法
  189.     protected function parsePhp($content) {
  190.         if(ini_get('short_open_tag')){
  191.             // 开启短标签的情况要将<?标签用echo方式输出 否则无法正常输出xml标识
  192.             $content = preg_replace('/(<\?(?!php|=|$))/i', '<?php echo \'\\1\'; ?>'."\n", $content );
  193.         }
  194.         // PHP语法检查
  195.         if(C('TMPL_DENY_PHP') && false !== strpos($content,'<?php')) {
  196.             E(L('_NOT_ALLOW_PHP_'));
  197.         }
  198.         return $content;
  199.     }
  200.  
  201.     // 解析模板中的布局标签
  202.     protected function parseLayout($content) {
  203.         // 读取模板中的布局标签
  204.         $find = preg_match('/'.$this->config['taglib_begin'].'layout\s(.+?)\s*?\/'.$this->config['taglib_end'].'/is',$content,$matches);
  205.         if($find) {
  206.             //替换Layout标签
  207.             $content    =   str_replace($matches[0],'',$content);
  208.             //解析Layout标签
  209.             $array      =   $this->parseXmlAttrs($matches[1]);
  210.             if(!C('LAYOUT_ON') || C('LAYOUT_NAME') !=$array['name'] ) {
  211.                 // 读取布局模板
  212.                 $layoutFile =   THEME_PATH.$array['name'].$this->config['template_suffix'];
  213.                 $replace    =   isset($array['replace'])?$array['replace']:$this->config['layout_item'];
  214.                 // 替换布局的主体内容
  215.                 $content    =   str_replace($replace,$content,file_get_contents($layoutFile));
  216.             }
  217.         }else{
  218.             $content = str_replace('{__NOLAYOUT__}','',$content);
  219.         }
  220.         return $content;
  221.     }
  222.  
  223.     // 解析模板中的include标签
  224.     protected function parseInclude($content, $extend = true) {
  225.         // 解析继承
  226.         if($extend)
  227.             $content    =   $this->parseExtend($content);
  228.         // 解析布局
  229.         $content    =   $this->parseLayout($content);
  230.         // 读取模板中的include标签
  231.         $find       =   preg_match_all('/'.$this->config['taglib_begin'].'include\s(.+?)\s*?\/'.$this->config['taglib_end'].'/is',$content,$matches);
  232.         if($find) {
  233.             for($i=0;$i<$find;$i++) {
  234.                 $include    =   $matches[1][$i];
  235.                 $array      =   $this->parseXmlAttrs($include);
  236.                 $file       =   $array['file'];
  237.                 unset($array['file']);
  238.                 $content    =   str_replace($matches[0][$i],$this->parseIncludeItem($file,$array,$extend),$content);
  239.             }
  240.         }
  241.         return $content;
  242.     }
  243.  
  244.     // 解析模板中的extend标签
  245.     protected function parseExtend($content) {
  246.         $begin      =   $this->config['taglib_begin'];
  247.         $end        =   $this->config['taglib_end'];        
  248.         // 读取模板中的继承标签
  249.         $find       =   preg_match('/'.$begin.'extend\s(.+?)\s*?\/'.$end.'/is',$content,$matches);
  250.         if($find) {
  251.             //替换extend标签
  252.             $content    =   str_replace($matches[0],'',$content);
  253.             // 记录页面中的block标签
  254.             preg_replace_callback('/'.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/is', array($this, 'parseBlock'),$content);
  255.             // 读取继承模板
  256.             $array      =   $this->parseXmlAttrs($matches[1]);
  257.             $content    =   $this->parseTemplateName($array['name']);
  258.             $content    =   $this->parseInclude($content, false); //对继承模板中的include进行分析
  259.             // 替换block标签
  260.             $content = $this->replaceBlock($content);
  261.         }else{
  262.             $content    =   preg_replace_callback('/'.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/is', function($match){return stripslashes($match[2]);}, $content);
  263.         }
  264.         return $content;
  265.     }
  266.  
  267.     /**
  268.      * 分析XML属性
  269.      * @access private
  270.      * @param string $attrs  XML属性字符串
  271.      * @return array
  272.      */
  273.     private function parseXmlAttrs($attrs) {
  274.         $xml        =   '<tpl><tag '.$attrs.' /></tpl>';
  275.         $xml        =   simplexml_load_string($xml);
  276.         if(!$xml)
  277.             E(L('_XML_TAG_ERROR_'));
  278.         $xml        =   (array)($xml->tag->attributes());
  279.         $array      =   array_change_key_case($xml['@attributes']);
  280.         return $array;
  281.     }
  282.  
  283.     /**
  284.      * 替换页面中的literal标签
  285.      * @access private
  286.      * @param string $content  模板内容
  287.      * @return string|false
  288.      */
  289.     private function parseLiteral($content) {
  290.         if(is_array($content)) $content = $content[1];
  291.         if(trim($content)=='')  return '';
  292.         //$content            =   stripslashes($content);
  293.         $i                  =   count($this->literal);
  294.         $parseStr           =   "<!--###literal{$i}###-->";
  295.         $this->literal[$i]  =   $content;
  296.         return $parseStr;
  297.     }
  298.  
  299.     /**
  300.      * 还原被替换的literal标签
  301.      * @access private
  302.      * @param string $tag  literal标签序号
  303.      * @return string|false
  304.      */
  305.     private function restoreLiteral($tag) {
  306.         if(is_array($tag)) $tag = $tag[1];
  307.         // 还原literal标签
  308.         $parseStr   =  $this->literal[$tag];
  309.         // 销毁literal记录
  310.         unset($this->literal[$tag]);
  311.         return $parseStr;
  312.     }
  313.  
  314.     /**
  315.      * 记录当前页面中的block标签
  316.      * @access private
  317.      * @param string $name block名称
  318.      * @param string $content  模板内容
  319.      * @return string
  320.      */
  321.     private function parseBlock($name,$content = '') {
  322.         if(is_array($name)){
  323.             $content = $name[2];
  324.             $name    = $name[1];
  325.         }
  326.         $this->block[$name]  =   $content;
  327.         return '';
  328.     }
  329.  
  330.     /**
  331.      * 替换继承模板中的block标签
  332.      * @access private
  333.      * @param string $content  模板内容
  334.      * @return string
  335.      */
  336.     private function replaceBlock($content){
  337.         static $parse = 0;
  338.         $begin = $this->config['taglib_begin'];
  339.         $end   = $this->config['taglib_end'];
  340.         $reg   = '/('.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.')(.*?)'.$begin.'\/block'.$end.'/is';
  341.         if(is_string($content)){
  342.             do{
  343.                 $content = preg_replace_callback($reg, array($this, 'replaceBlock'), $content);
  344.             } while ($parse && $parse--);
  345.             return $content;
  346.         } elseif(is_array($content)){
  347.             if(preg_match('/'.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.'/is', $content[3])){ //存在嵌套,进一步解析
  348.                 $parse = 1;
  349.                 $content[3] = preg_replace_callback($reg, array($this, 'replaceBlock'), "{$content[3]}{$begin}/block{$end}");
  350.                 return $content[1] . $content[3];
  351.             } else {
  352.                 $name    = $content[2];
  353.                 $content = $content[3];
  354.                 $content = isset($this->block[$name]) ? $this->block[$name] : $content;
  355.                 return $content;
  356.             }
  357.         }
  358.     }
  359.  
  360.     /**
  361.      * 搜索模板页面中包含的TagLib库
  362.      * 并返回列表
  363.      * @access public
  364.      * @param string $content  模板内容
  365.      * @return string|false
  366.      */
  367.     public function getIncludeTagLib(& $content) {
  368.         //搜索是否有TagLib标签
  369.         $find = preg_match('/'.$this->config['taglib_begin'].'taglib\s(.+?)(\s*?)\/'.$this->config['taglib_end'].'\W/is',$content,$matches);
  370.         if($find) {
  371.             //替换TagLib标签
  372.             $content        =   str_replace($matches[0],'',$content);
  373.             //解析TagLib标签
  374.             $array          =   $this->parseXmlAttrs($matches[1]);
  375.             $this->tagLib   =   explode(',',$array['name']);
  376.         }
  377.         return;
  378.     }
  379.  
  380.     /**
  381.      * TagLib库解析
  382.      * @access public
  383.      * @param string $tagLib 要解析的标签库
  384.      * @param string $content 要解析的模板内容
  385.      * @param boolean $hide 是否隐藏标签库前缀
  386.      * @return string
  387.      */
  388.     public function parseTagLib($tagLib,&$content,$hide=false) {
  389.         $begin      =   $this->config['taglib_begin'];
  390.         $end        =   $this->config['taglib_end'];
  391.         if(strpos($tagLib,'\\')){
  392.             // 支持指定标签库的命名空间
  393.             $className  =   $tagLib;
  394.             $tagLib     =   substr($tagLib,strrpos($tagLib,'\\')+1);
  395.         }else{
  396.             $className  =   'Think\\Template\TagLib\\'.ucwords($tagLib);            
  397.         }
  398.         $tLib       =   \Think\Think::instance($className);
  399.         $that       =   $this;
  400.         foreach ($tLib->getTags() as $name=>$val){
  401.             $tags = array($name);
  402.             if(isset($val['alias'])) {// 别名设置
  403.                 $tags       = explode(',',$val['alias']);
  404.                 $tags[]     =  $name;
  405.             }
  406.             $level      =   isset($val['level'])?$val['level']:1;
  407.             $closeTag   =   isset($val['close'])?$val['close']:true;
  408.             foreach ($tags as $tag){
  409.                 $parseTag = !$hide? $tagLib.':'.$tag: $tag;// 实际要解析的标签名称
  410.                 if(!method_exists($tLib,'_'.$tag)) {
  411.                     // 别名可以无需定义解析方法
  412.                     $tag  =  $name;
  413.                 }
  414.                 $n1 = empty($val['attr'])?'(\s*?)':'\s([^'.$end.']*)';
  415.                 $this->tempVar = array($tagLib, $tag);
  416.  
  417.                 if (!$closeTag){
  418.                     $patterns       = '/'.$begin.$parseTag.$n1.'\/(\s*?)'.$end.'/is';
  419.                     $content        = preg_replace_callback($patterns, function($matches) use($tLib,$tag,$that){
  420.                         return $that->parseXmlTag($tLib,$tag,$matches[1],$matches[2]);
  421.                     },$content);
  422.                 }else{
  423.                     $patterns       = '/'.$begin.$parseTag.$n1.$end.'(.*?)'.$begin.'\/'.$parseTag.'(\s*?)'.$end.'/is';
  424.                     for($i=0;$i<$level;$i++) {
  425.                         $content=preg_replace_callback($patterns,function($matches) use($tLib,$tag,$that){
  426.                             return $that->parseXmlTag($tLib,$tag,$matches[1],$matches[2]);
  427.                         },$content);
  428.                     }
  429.                 }
  430.             }
  431.         }
  432.     }
  433.  
  434.     /**
  435.      * 解析标签库的标签
  436.      * 需要调用对应的标签库文件解析类
  437.      * @access public
  438.      * @param object $tagLib  标签库对象实例
  439.      * @param string $tag  标签名
  440.      * @param string $attr  标签属性
  441.      * @param string $content  标签内容
  442.      * @return string|false
  443.      */
  444.     public function parseXmlTag($tagLib,$tag,$attr,$content) {
  445.         if(ini_get('magic_quotes_sybase'))
  446.             $attr   =   str_replace('\"','\'',$attr);
  447.         $parse      =   '_'.$tag;
  448.         $content    =   trim($content);
  449.         $tags       =   $tagLib->parseXmlAttr($attr,$tag);
  450.         return $tagLib->$parse($tags,$content);
  451.     }
  452.  
  453.     /**
  454.      * 模板标签解析
  455.      * 格式: {TagName:args [|content] }
  456.      * @access public
  457.      * @param string $tagStr 标签内容
  458.      * @return string
  459.      */
  460.     public function parseTag($tagStr){
  461.         if(is_array($tagStr)) $tagStr = $tagStr[2];
  462.         //if (MAGIC_QUOTES_GPC) {
  463.             $tagStr = stripslashes($tagStr);
  464.         //}
  465.         $flag   =  substr($tagStr,0,1);
  466.         $flag2  =  substr($tagStr,1,1);
  467.         $name   = substr($tagStr,1);
  468.         if('$' == $flag && '.' != $flag2 && '(' != $flag2){ //解析模板变量 格式 {$varName}
  469.             return $this->parseVar($name);
  470.         }elseif('-' == $flag || '+'== $flag){ // 输出计算
  471.             return  '<?php echo '.$flag.$name.';?>';
  472.         }elseif(':' == $flag){ // 输出某个函数的结果
  473.             return  '<?php echo '.$name.';?>';
  474.         }elseif('~' == $flag){ // 执行某个函数
  475.             return  '<?php '.$name.';?>';
  476.         }elseif(substr($tagStr,0,2)=='//' || (substr($tagStr,0,2)=='/*' && substr(rtrim($tagStr),-2)=='*/')){
  477.             //注释标签
  478.             return '';
  479.         }
  480.         // 未识别的标签直接返回
  481.         return C('TMPL_L_DELIM') . $tagStr .C('TMPL_R_DELIM');
  482.     }
  483.  
  484.     /**
  485.      * 模板变量解析,支持使用函数
  486.      * 格式: {$varname|function1|function2=arg1,arg2}
  487.      * @access public
  488.      * @param string $varStr 变量数据
  489.      * @return string
  490.      */
  491.     public function parseVar($varStr){
  492.         $varStr     =   trim($varStr);
  493.         static $_varParseList = array();
  494.         //如果已经解析过该变量字串,则直接返回变量值
  495.         if(isset($_varParseList[$varStr])) return $_varParseList[$varStr];
  496.         $parseStr   =   '';
  497.         $varExists  =   true;
  498.         if(!empty($varStr)){
  499.             $varArray = explode('|',$varStr);
  500.             //取得变量名称
  501.             $var = array_shift($varArray);
  502.             if('Think.' == substr($var,0,6)){
  503.                 // 所有以Think.打头的以特殊变量对待 无需模板赋值就可以输出
  504.                 $name = $this->parseThinkVar($var);
  505.             }elseif( false !== strpos($var,'.')) {
  506.                 //支持 {$var.property}
  507.                 $vars = explode('.',$var);
  508.                 $var  =  array_shift($vars);
  509.                 switch(strtolower(C('TMPL_VAR_IDENTIFY'))) {
  510.                     case 'array': // 识别为数组
  511.                         $name = '$'.$var;
  512.                         foreach ($vars as $key=>$val)
  513.                             $name .= '["'.$val.'"]';
  514.                         break;
  515.                     case 'obj':  // 识别为对象
  516.                         $name = '$'.$var;
  517.                         foreach ($vars as $key=>$val)
  518.                             $name .= '->'.$val;
  519.                         break;
  520.                     default:  // 自动判断数组或对象 只支持二维
  521.                         $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0];
  522.                 }
  523.             }elseif(false !== strpos($var,'[')) {
  524.                 //支持 {$var['key']} 方式输出数组
  525.                 $name = "$".$var;
  526.                 preg_match('/(.+?)\[(.+?)\]/is',$var,$match);
  527.                 $var = $match[1];
  528.             }elseif(false !==strpos($var,':') && false ===strpos($var,'(') && false ===strpos($var,'::') && false ===strpos($var,'?')){
  529.                 //支持 {$var:property} 方式输出对象的属性
  530.                 $vars = explode(':',$var);
  531.                 $var  =  str_replace(':','->',$var);
  532.                 $name = "$".$var;
  533.                 $var  = $vars[0];
  534.             }else {
  535.                 $name = "$$var";
  536.             }
  537.             //对变量使用函数
  538.             if(count($varArray)>0)
  539.                 $name = $this->parseVarFunction($name,$varArray);
  540.             $parseStr = '<?php echo ('.$name.'); ?>';
  541.         }
  542.         $_varParseList[$varStr] = $parseStr;
  543.         return $parseStr;
  544.     }
  545.  
  546.     /**
  547.      * 对模板变量使用函数
  548.      * 格式 {$varname|function1|function2=arg1,arg2}
  549.      * @access public
  550.      * @param string $name 变量名
  551.      * @param array $varArray  函数列表
  552.      * @return string
  553.      */
  554.     public function parseVarFunction($name,$varArray){
  555.         //对变量使用函数
  556.         $length = count($varArray);
  557.         //取得模板禁止使用函数列表
  558.         $template_deny_funs = explode(',',C('TMPL_DENY_FUNC_LIST'));
  559.         for($i=0;$i<$length ;$i++ ){
  560.             $args = explode('=',$varArray[$i],2);
  561.             //模板函数过滤
  562.             $fun = trim($args[0]);
  563.             switch($fun) {
  564.             case 'default':  // 特殊模板函数
  565.                 $name = '(isset('.$name.') && ('.$name.' !== ""))?('.$name.'):'.$args[1];
  566.                 break;
  567.             default:  // 通用模板函数
  568.                 if(!in_array($fun,$template_deny_funs)){
  569.                     if(isset($args[1])){
  570.                         if(strstr($args[1],'###')){
  571.                             $args[1] = str_replace('###',$name,$args[1]);
  572.                             $name = "$fun($args[1])";
  573.                         }else{
  574.                             $name = "$fun($name,$args[1])";
  575.                         }
  576.                     }else if(!empty($args[0])){
  577.                         $name = "$fun($name)";
  578.                     }
  579.                 }
  580.             }
  581.         }
  582.         return $name;
  583.     }
  584.  
  585.     /**
  586.      * 特殊模板变量解析
  587.      * 格式 以 $Think. 打头的变量属于特殊模板变量
  588.      * @access public
  589.      * @param string $varStr  变量字符串
  590.      * @return string
  591.      */
  592.     public function parseThinkVar($varStr){
  593.         $vars = explode('.',$varStr);
  594.         $vars[1] = strtoupper(trim($vars[1]));
  595.         $parseStr = '';
  596.         if(count($vars)>=3){
  597.             $vars[2] = trim($vars[2]);
  598.             switch($vars[1]){
  599.                 case 'SERVER':
  600.                     $parseStr = '$_SERVER[\''.strtoupper($vars[2]).'\']';break;
  601.                 case 'GET':
  602.                     $parseStr = '$_GET[\''.$vars[2].'\']';break;
  603.                 case 'POST':
  604.                     $parseStr = '$_POST[\''.$vars[2].'\']';break;
  605.                 case 'COOKIE':
  606.                     if(isset($vars[3])) {
  607.                         $parseStr = '$_COOKIE[\''.$vars[2].'\'][\''.$vars[3].'\']';
  608.                     }else{
  609.                         $parseStr = 'cookie(\''.$vars[2].'\')';
  610.                     }
  611.                     break;
  612.                 case 'SESSION':
  613.                     if(isset($vars[3])) {
  614.                         $parseStr = '$_SESSION[\''.$vars[2].'\'][\''.$vars[3].'\']';
  615.                     }else{
  616.                         $parseStr = 'session(\''.$vars[2].'\')';
  617.                     }
  618.                     break;
  619.                 case 'ENV':
  620.                     $parseStr = '$_ENV[\''.strtoupper($vars[2]).'\']';break;
  621.                 case 'REQUEST':
  622.                     $parseStr = '$_REQUEST[\''.$vars[2].'\']';break;
  623.                 case 'CONST':
  624.                     $parseStr = strtoupper($vars[2]);break;
  625.                 case 'LANG':
  626.                     $parseStr = 'L("'.$vars[2].'")';break;
  627.                 case 'CONFIG':
  628.                     if(isset($vars[3])) {
  629.                         $vars[2] .= '.'.$vars[3];
  630.                     }
  631.                     $parseStr = 'C("'.$vars[2].'")';break;
  632.                 default:break;
  633.             }
  634.         }else if(count($vars)==2){
  635.             switch($vars[1]){
  636.                 case 'NOW':
  637.                     $parseStr = "date('Y-m-d g:i a',time())";
  638.                     break;
  639.                 case 'VERSION':
  640.                     $parseStr = 'THINK_VERSION';
  641.                     break;
  642.                 case 'TEMPLATE':
  643.                     $parseStr = "'".$this->templateFile."'";//'C("TEMPLATE_NAME")';
  644.                     break;
  645.                 case 'LDELIM':
  646.                     $parseStr = 'C("TMPL_L_DELIM")';
  647.                     break;
  648.                 case 'RDELIM':
  649.                     $parseStr = 'C("TMPL_R_DELIM")';
  650.                     break;
  651.                 default:
  652.                     if(defined($vars[1]))
  653.                         $parseStr = $vars[1];
  654.             }
  655.         }
  656.         return $parseStr;
  657.     }
  658.  
  659.     /**
  660.      * 加载公共模板并缓存 和当前模板在同一路径,否则使用相对路径
  661.      * @access private
  662.      * @param string $tmplPublicName  公共模板文件名
  663.      * @param array $vars  要传递的变量列表
  664.      * @return string
  665.      */
  666.     private function parseIncludeItem($tmplPublicName,$vars=array(),$extend){
  667.         // 分析模板文件名并读取内容
  668.         $parseStr = $this->parseTemplateName($tmplPublicName);
  669.         // 替换变量
  670.         foreach ($vars as $key=>$val) {
  671.             $parseStr = str_replace('['.$key.']',$val,$parseStr);
  672.         }
  673.         // 再次对包含文件进行模板分析
  674.         return $this->parseInclude($parseStr,$extend);
  675.     }
  676.  
  677.     /**
  678.      * 分析加载的模板文件并读取内容 支持多个模板文件读取
  679.      * @access private
  680.      * @param string $tmplPublicName  模板文件名
  681.      * @return string
  682.      */    
  683.     private function parseTemplateName($templateName){
  684.         if(substr($templateName,0,1)=='$')
  685.             //支持加载变量文件名
  686.             $templateName = $this->get(substr($templateName,1));
  687.         $array  =   explode(',',$templateName);
  688.         $parseStr   =   '';
  689.         foreach ($array as $templateName){
  690.             if(empty($templateName)) continue;
  691.             if(false === strpos($templateName,$this->config['template_suffix'])) {
  692.                 // 解析规则为 模块@主题/控制器/操作
  693.                 $templateName   =   T($templateName);
  694.             }
  695.             // 获取模板文件内容
  696.             $parseStr .= file_get_contents($templateName);
  697.         }
  698.         return $parseStr;
  699.     }    
  700. }
  701.  
downloadTemplate.class.php Source code - Download The latest thinkphp v5.2 work order system Source code
Related Source Codes/Software:
V3.3.6 Workerman high-performance PHP Socket (framework) - High performance PHP Socket framework Workerman re... 2017-05-03
The phosphor meeting room reservation system MRBS (loop reservation v16.0) - The phosphor meeting room reservation system MRBS ... 2017-05-03
IDC v5.2.3 agent center - IDC Centre IDC for exploitation is a PHP+MySQL age... 2017-05-03
Zen master v9.0.1 project management software - Zen is the first domestic open source project mana... 2017-05-03
Ray speed v7.03 employee files management system - Employee files project is various, and some conten... 2017-05-03
HITCMS Haitian responsive electronic mechanical v3.0 foreign trade website source code - HITCMS Haitian response electronic machinery trade... 2017-05-03
Ray v7.02 speed survey system - Lightning speed survey system is a. NET+MSSQL deve... 2017-05-03
Cool HITCMS reactive black v3.0 enterprise website source code - HITCMS-Haitian response black enterprises website ... 2017-05-03
WebOA v17.2 network office automation system - WebOA network using b/s structure development of o... 2017-05-03
Pure imitation of han site source code, one a 】 【 c9cms kernel v1.0 - Generic http://www.wufazhuce.com/Han one · Config... 2017-05-04
zone.js - Implements Zones for JavaScript ... 2017-05-11
dragonfly - A Ruby gem for on-the-fly processing - suitable fo... 2017-05-11
oh-my-fish - The Fishshell Framework. 2017-05-11
canvas-lms - The open LMS by Instructure, Inc. 2017-05-11
ledger - Double-entry accounting system with a command-line... 2017-05-11
Python - My Python Examples http://w... 2017-05-11
blade - 2017-05-11
LaZagne - Credentials recovery project 2017-05-10
Pull-to-Refresh.Rentals-iOS - This project aims to provide a simple and customiz... 2017-05-10
spoon - Distributing instrumentation tests to all your And... 2017-05-10

 Back to top