www.gusucode.com > Ectouch手机端网购商城系统PHP版源码程序 > ectouch/include/EcTemplate.class.php
<?php /** * ECTouch Open Source Project * ============================================================================ * Copyright (c) 2012-2014 http://ectouch.cn All rights reserved. * ---------------------------------------------------------------------------- * 文件名称:EcTemplate.class.php * ---------------------------------------------------------------------------- * 功能描述:模板类 * ---------------------------------------------------------------------------- * Licensed ( http://www.ectouch.cn/docs/license.txt ) * ---------------------------------------------------------------------------- */ /* 访问控制 */ defined('IN_ECTOUCH') or die('Deny Access'); class EcTemplate { public $config = array(); //配置 protected $vars = array(); //存放变量信息 protected $_replace = array(); /** * 构造函数 * @param unknown $config */ public function __construct($config = array()) { $this->config = array_merge(C('TPL'), (array) $config); //参数配置 $this->assign('EcTemplate', $this); $this->_replace = array( 'str' => array('search' => array(), 'replace' => array() ), 'reg' => array('search' => array("/__[A-Z]+__/", //替换常量 "/{include\s*file=\"(.*)\"}/i", //递归解析模板包含 ), 'replace' => array("<?php echo $0;?>", "<?php \$EcTemplate->display(\"$1\"); ?>", ) ) ); } /** * 模板赋值 * @param unknown $name * @param string $value */ public function assign($name, $value = '') { if (is_array($name)) { foreach ($name as $k => $v) { $this->vars[$k] = $v; } } else { $this->vars[$name] = $value; } } /** * 执行模板解析输出 * @param string $tpl * @param string $return * @param string $is_tpl * @throws Exception * @return string */ public function display($tpl = '', $return = false, $is_tpl = true) { //如果没有设置模板,则调用当前模块的当前操作模板 if ($is_tpl && ($tpl == "") && (!empty($_GET['_module'])) && (!empty($_GET['_action']))) { $tpl = $_GET['_module'] . "/" . $_GET['_action']; } if ($return) { if (ob_get_level()) { ob_end_flush(); flush(); } ob_start(); } extract($this->vars, EXTR_OVERWRITE); if ($is_tpl && $this->config['TPL_CACHE_ON']) { define('ECTOUCH', true); $tplFile = $this->config['TPL_TEMPLATE_PATH'] . $tpl . $this->config['TPL_TEMPLATE_SUFFIX']; $cacheFile = $this->config['TPL_CACHE_PATH'] . md5($tplFile) . $this->config['TPL_CACHE_SUFFIX']; if (!file_exists($tplFile)) { exit($tplFile . "模板文件不存在"); } //普通的文件缓存 if (empty($this->config['TPL_CACHE_TYPE'])) { if (!is_dir($this->config['TPL_CACHE_PATH'])) { @mkdir($this->config['TPL_CACHE_PATH'], 0777, true); } if ((!file_exists($cacheFile)) || (filemtime($tplFile) > filemtime($cacheFile))) { file_put_contents($cacheFile, "<?php if (!defined('ECTOUCH')) exit;?>" . $this->compile($tpl)); //写入缓存 } include( $cacheFile ); //加载编译后的模板缓存 } else { //支持memcache等缓存 $tpl_key = md5(realpath($tplFile)); $tpl_time_key = $tpl_key . '_time'; static $cache = NULL; $cache = is_object($cache) ? $cache : new EcCache($this->config, $this->config['TPL_CACHE_TYPE']); $compile_content = $cache->get($tpl_key); if (empty($compile_content) || (filemtime($tplFile) > $cache->get($tpl_time_key))) { $compile_content = $this->compile($tpl); $cache->set($tpl_key, $compile_content, 3600 * 24 * 365); //缓存编译内容 $cache->set($tpl_time_key, time(), 3600 * 24 * 365); //缓存编译内容 } exit($compile_content); eval('?>' . $compile_content); } } else { eval('?>' . $this->compile($tpl, $is_tpl)); //直接执行编译后的模板 } if ($return) { $content = ob_get_contents(); ob_end_clean(); return $content; } } /** * 自定义添加标签 * @param unknown $tags * @param string $reg */ public function addTags($tags = array(), $reg = false) { $flag = $reg ? 'reg' : 'str'; foreach ($tags as $k => $v) { $this->_replace[$flag]['search'][] = $k; $this->_replace[$flag]['replace'][] = $v; } } /** * 模板编译核心 * @param unknown $tpl * @param string $is_tpl * @throws Exception * @return mixed */ protected function compile($tpl, $is_tpl = true) { if ($is_tpl) { $tplFile = $this->config['TPL_TEMPLATE_PATH'] . $tpl . $this->config['TPL_TEMPLATE_SUFFIX']; if (!file_exists($tplFile)) { exit($tplFile . "模板文件不存在"); } $template = file_get_contents($tplFile); } else { extract($this->vars, EXTR_OVERWRITE); $template = $tpl; } //如果自定义模板标签解析函数tpl_parse_ext($template)存在,则执行 if (function_exists('tpl_parse_ext')) { $template = tpl_parse_ext($template); } $template = str_replace($this->_replace['str']['search'], $this->_replace['str']['replace'], $template); $template = preg_replace($this->_replace['reg']['search'], $this->_replace['reg']['replace'], $template); $template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", '{$1}', $template); // 普通变量数组转化. $varRegexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\-\>)?[a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)"; $varRegexp2 = "\{((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\-\>)?[a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)\}"; $const_regexp = "([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)"; $template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", '<?=$1?>', $template); $template = preg_replace_callback("/$varRegexp2/is", array(&$this,'preg__var'), $template); $template = preg_replace_callback("/$varRegexp/is", array(&$this,'preg__var'), $template); $template = preg_replace_callback("/\<\?\=\<\?\=$varRegexp\?\>\?\>/is",array(&$this,'preg__var'), $template,-1,$regint); $template = strtr($template, array('<?php' => '<?', '<?php echo' => '<?=','?><?php'=>' ')); $template = strtr($template, array('<?' => '<?php', '<?=' => '<?php echo ')); return $template; } } function preg__var($math){ if(is_string($math) === false) $math = $math[1]; $returnstr = ''; if($math){ $math = trim($math, '<>?='); $varname = "<?={$math}?>"; $returnstr = str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/sU", "['\\1']", $varname)); } return $returnstr; }