StarTemplate_set = array( /* 模板语法前后标示符 */ 'left_tag' => '{', 'right_tag' => '}', /* 模板路径,以default为默认模板 (详细使用方法,请查看官方手册) */ 'templateDir' => array('default' => 'template/'.$template_Name), /* 默认使用模板,此与模板路径键对应 */ 'template_Name' => 'default', /* 模板文件后缀名 */ 'templateExt' => '.html', /* 是否持续编译模板 (用于调试时用) */ 'force_compile' => FALSE, /* 是否开启直接插入PHP代码 */ 'PHP_off' => FALSE, /* 定义模板编译目录,结尾不要加斜杠 '/' */ 'templateCompileDir' => 'data/cache/compile', /* 模板编译文件的后缀名 */ 'templateCompileExt' => '.phpc', /* 是否使用输出缓存 */ 'cache_is' => FALSE, /* 输出缓存标示符 默认为 当前URL 的MD5值 */ /* * 此功能,在您在调用输出缓存时,需要指定的,以防止模板缓存重复,以影响您的程序输出 * 可在使用时,自行定义 * */ 'cacheId' => md5($_SERVER['REQUEST_URI']), /* 输出缓存时间 单位秒 */ 'cache_time' => 10, /* 输出缓存目录,结尾不要加斜杠 '/' */ 'templateCacheDir' => 'data/cache/template', /* 输出缓存文件后缀名 */ 'templateCacheExt' => '.phpo', /* 扩展功能(Function)插件存放路径,结尾不要加斜杠 '/' */ 'templatePluginsDir' => 'StarTemplate_Plugins', /* 由本程序所创建的目录权限 代码 */ 'dir_mode' => 0777, /* 被编译模板文件的大小限制 单位 M */ 'file_max' => 1, /* 开启Gzip传输,提高传输速度 (此功能只在使用display是适用) */ 'gzip_off' => false, /* 兼容选项,如果模板引擎输出空白,请开启此项 */ 'compatible' => true, /* 此为调试时开启,可自动弹出一个窗口,窗口里为 StarTemplate 模板引擎的所有配置文件,包括注入的资源 (方便调试) */ 'debug' => false, /* 是否存在已定义的 error_reporting */ 'error_reporting' => false, 'classDir' => FCPATH /* 默认的提示语言为中文, 您可以编写简单的语言包,为此程序增加提示语言的可读性 */ ); $this->setConfig($this->StarTemplate_set); } } class StarTemplate { // 引擎选项 private $arrayConfig = array(); /* 模板编译信息提示 默认中文 ( 如果特定语言包存在,将自动读取 ) */ public $StarTemplate_Class_Lang = array( ' 模板文件不存在或读取失败', ' 模板文件大小超出限制', ' 模板文件没有正常加载', '严重错误', '程序警告', '语法错误', '文件名称', '错误等级', '错误所在', '错误信息', '缓存文件路径', '错误源产生在', ); // 类实例化 (进行数组设置) public function __construct($arrayConfig = array()) { /* 获取当前类所在目录 */ $this->arrayConfig['classDir'] = dirname(str_replace('\\','/',__FILE__)); /* 载入配置 */ $this->arrayConfig += $arrayConfig; /* 获取当前类名称 (防止类名称修改,导致报错机制失败) */ $this->arrayConfig['ClassName'] = __CLASS__; /* 类被初始化时 自动读取语言包 (并判断语言包是否有效) */ global $_StarTemplate_Class_Lang; if (is_array($_StarTemplate_Class_Lang)) { $this->StarTemplate_Class_Lang += $_StarTemplate_Class_Lang; } /* 载入扩展功能文件 */ $Plugins = $this->get_Template_Plugins(); if (is_array($Plugins)) { foreach ($Plugins as $p_path){ include $p_path; } } } /* 设置引擎 */ public function setConfig($key, $value = null) { if (is_array($key)) { $this->arrayConfig += $key; }else{ $this->arrayConfig[$key] = $value; } } /* 获取当前模板引擎配置 */ public function getConfig($key = null) { if ($key) { return $this->arrayConfig[$key]; } return $this->arrayConfig; } /* 向模板引擎中注入变量 */ public function assign($key,$val = null) { if (empty($key)) return ''; if (is_array($key)) { foreach ($key as $k=>$v) { $this->arrayConfig['GLOBALS'][$k] = $v; } }else{ $this->arrayConfig['GLOBALS'][$key] = $val; } } /* 取得变量值 */ private function & get_Value($key) { if (isset($this->arrayConfig['GLOBALS'][$key])) { return $this->arrayConfig['GLOBALS'][$key]; }else{ global $$key; if ($$key) { $this->assign($key,$$key); } return $$key; } } /* 取得模板路径 */ private function get_Template_Path($templateName) { return $this->arrayConfig['templateDir'][(empty($this->arrayConfig['template_Name']) ? 'default' : $this->arrayConfig['template_Name'])].'/'.$templateName.$this->arrayConfig['templateExt']; } /* 获取模板编译路径 */ private function get_Template_Compile_Path($templateName) { return $this->arrayConfig['classDir'].'/'.$this->arrayConfig['templateCompileDir'].'/'.md5($this->get_Template_Path($templateName)).$this->arrayConfig['templateCompileExt']; } /* 获取模板缓存路径 */ private function get_Template_Cache_Path($templateName, $all = false) { if ($all) { if ($all === true) { $tmp_path = md5($templateName).'*'; }else{ $tmp_path = md5($templateName).$all; } }else{ $tmp_path = md5($templateName).$this->arrayConfig['cacheId']; } return $this->arrayConfig['classDir'].'/'.$this->arrayConfig['templateCacheDir'].'/'.$tmp_path.$this->arrayConfig['templateCacheExt']; } /* 获取扩展功能文件列表 */ private function get_Template_Plugins() { if (is_dir($this->arrayConfig['classDir'].'/'.$this->arrayConfig['templatePluginsDir'].'/')) { return glob($this->arrayConfig['classDir'].'/'.$this->arrayConfig['templatePluginsDir'].'/*.php'); } } /* 判断缓存输出是否有效/是否开启缓存输出 */ public function is_cached($templateName) { $_PATH = $this->get_Template_Cache_Path($templateName); if (!file_exists($_PATH)) { return false; }elseif (filemtime($_PATH) + $this->arrayConfig['cache_time'] < time()){ return false; }else{ return true; } } /* 读取文件 */ private function template_Read($PATH) { if (function_exists('file_get_contents')) { return file_get_contents($PATH); }else{ $fopen = fopen($PATH,'r'); $template_Content = ''; do { $data = fread($fopen,1024); if (strlen($data)===0) break; $template_Content .= $data; }while(1); fclose($fopen); return $template_Content; } } /* 写入文件 */ private function template_Write($PATH,$String) { /* 调用递归创建目录 */ $this->template_CreateDir(dirname($PATH)); /* 以写入方式打开文件句柄,开启 flock */ $fopen = fopen($PATH,'w'); flock($fopen, LOCK_EX + LOCK_NB); $fwrite = fwrite($fopen,$String); /* 失败重新尝试写入 */ if (!$fwrite) $fwrite = fwrite($fopen,$String); flock($fopen, LOCK_UN + LOCK_NB); fclose($fopen); return $fwrite; } /* 循环创建目录 */ private function template_CreateDir($Dir) { if (is_dir($Dir)) return true; if (mkdir($Dir, $this->arrayConfig['dir_mode'])) return true; if (!$this->template_CreateDir(dirname($Dir))) return false; return mkdir($Dir, $this->arrayConfig['dir_mode']); } public function getMicrotime() { list($microtime_1,$microtime_2) = explode(' ',microtime()); return $microtime_1 + $microtime_2; } /* 输出模板 */ public function display($templateName, $key = '',$Clean = 0) { $this->StarTemplate_Display($templateName,$Clean,'display',$key); } /* 返回输出模板 */ public function fetch($templateName, $key = '') { $Clean = 0; return $this->StarTemplate_Display($templateName,$Clean,'output',$key); } /* 输出模板 */ private function StarTemplate_Display($templateName,$Clean = 0,$display = '',$key = '') { /* 定义错误信息 */ if (!$this->arrayConfig['error_reporting']) { $StarTemplate_old_err = error_reporting(); error_reporting(E_ERROR | E_WARNING | E_PARSE); } /* 设定模板 */ if ($key) { $tmp_key = $this->arrayConfig['template_Name']; $this->arrayConfig['template_Name'] = $key; } /* 引擎运行时间统计 */ $this->arrayConfig['Runtime'] = $this->getMicrotime(); if ($this->arrayConfig['cache_is']) $_PATH = $this->get_Template_Cache_Path($templateName); if (!$this->is_cached($templateName) || $Clean) { /* 将错误载入特定函数处理 */ if ($this->arrayConfig['compatible']) { ob_start(); }else{ // 载入Debug类 //$class_debug = new StarTemplate_debug($this); //ob_start(array($class_debug,'StarTemplate_xError')); } /* 进行模板编译 */ include $this->StarTemplate_compile($templateName,$Clean); $StarTemplate_Content = ob_get_contents(); ob_end_clean(); }else{ /* 读取缓存输出文件 */ $StarTemplate_Content = $this->template_Read($_PATH); } /* 判断是否可以写入缓存输出内容 */ if ($this->arrayConfig['cache_is']) { /* 判断缓存输出是否有效 */ if (!$this->is_cached($templateName)) $this->template_write($_PATH,$StarTemplate_Content); } if ($this->arrayConfig['debug']) { unset($this->arrayConfig['GLOBALS'][$this->arrayConfig['ClassName']]); ob_start(); print_r($this->arrayConfig); $debug = ob_get_contents(); ob_end_clean(); $StarTemplate_Content .= '
'.''; } switch ($display) { case 'display': echo $StarTemplate_Content; $StarTemplate_Content = null; break; } /* 返回执行时间 */ $this->template_Runtime(); if (isset($tmp_key)) $this->arrayConfig['template_Name'] = $tmp_key; if ($this->arrayConfig['gzip_off'] && ereg('gzip',$_SERVER['HTTP_ACCEPT_ENCODING'])) { ob_start('ob_gzhandler'); } /* 定义错误信息 */ if (!$this->arrayConfig['error_reporting']) error_reporting($StarTemplate_old_err); return $StarTemplate_Content; } /*******************************************************************/ /* 编译开始 /*******************************************************************/ /* 转换标示符 */ private function ConverTag($Tag) { $_count = strlen($Tag); $new_array = array('{','}','[',']','$','(',')','*','+','.','?','\\','^','|'); $Tag_ = ''; for ($i=0;$i<$_count;$i++) { $Tag_ .= (in_array($Tag[$i],$new_array)?'\\':'').$Tag[$i]; } return $Tag_; } /* 模板引擎编译 */ private function StarTemplate_compile($templateName,$Clean = 0) { $_PATH = array(); /* 取得有效模板路径 */ $_PATH['From'] = $this->get_Template_Path($templateName); $_PATH['Save'] = $this->get_Template_Compile_Path($templateName); /* 判断模板文件是否存在 */ if (!file_exists($_PATH['From'])) return $_PATH['From'].' {'.$templateName.$this->StarTemplate_Class_Lang[0].'}'; /* 判断模板缓存文件是否需要更新 */ if ($this->arrayConfig['force_compile']) $Clean = 1; if (!$Clean) { if (file_exists($_PATH['From'])) $_fromt = filemtime($_PATH['From']); if (file_exists($_PATH['Save'])) $_savet = filemtime($_PATH['Save']); if ($_fromt <= $_savet) { return $_PATH['Save']; } } /* 判断模板文件大小限制 */ if (filesize($_PATH['From']) > $this->arrayConfig['file_max'] * 1024 * 1024) return $this->StarTemplate_Error($templateName.$this->StarTemplate_Class_Lang[1].' ('.$this->arrayConfig['file_max'].' M)'); /* 取得有效标示 */ $_Left = '(?ConverTag($this->arrayConfig['left_tag']); $_Right = '((?ConverTag($this->arrayConfig['right_tag']); /* 取得模板源 */ $StarTemplate_Conver = $this->template_read($_PATH['From']); /* 如果模板为空,不进行编译 */ if (empty($StarTemplate_Conver)) { $this->template_Write($_PATH['Save'],$StarTemplate_Conver); return $_PATH['Save']; } /* **************模板进行相关编译起始******************* */ /* Start// write by xbantu 2009-06-06 */ $StarTemplate_Conver = trim($StarTemplate_Conver); preg_match_all('/'.$_Left.'Template (([\w|-|\/]{1,})|(\$([_a-zA-Z][\w]+)))'.$_Right.'/',$StarTemplate_Conver,$Include_); $Include_count = count($Include_[0]); /* 模板文件嵌套调用处理 */ for ($i=0;$i< $Include_count;$i++) { /* 编译相应调入模板文件 */ $StarTemplate_Conver = str_replace($Include_[0][$i],$this->arrayConfig['left_tag'].'eval include $this->StarTemplate_compile("'.$Include_[1][$i].'")'.$this->arrayConfig['right_tag'],$StarTemplate_Conver); /* 2009-06-07 放弃使用模板状态提示 */ /* // 提示模板文件加载状态 $Include_Tmp_Name = $this->get_StarTemplate_path($Include_[1][$i]); $StarTemplate_Conver = str_replace($Include_[0][$i],$this->StarTemplate_Left.' '.$Include_[1][$i].$this->StarTemplate_Class_Lang[2].$this->StarTemplate_Right,$StarTemplate_Conver); */ } unset($Include_); /* 获取模板所使用变量 */ preg_match_all('/\$([_a-zA-Z][\w]+)/',$StarTemplate_Conver,$Global_var); if (is_array($Global_var[1])) { $Global_var[1] = array_unique($Global_var[1]); $Global_var_Im = array('this','_GET','_POST','_COOKIE','_SERVER','_SESSION','_FILES','_ENV'); $Global_var_out = ''; foreach ($Global_var[1] as $val) { if (!in_array($val,$Global_var_Im)) { $Global_var_out .= '$'.$val.' =& $this->get_Value(\''.$val.'\'); '; } } } /* 相关标签转换 */ $Template_preg = array(); $Template_Replace = array(); /* 判断是否允许插入PHP */ if ($this->arrayConfig['PHP_off'] === false) { $StarTemplate_Preg[] = '/<\?(=|php|)(.+?)\?>/is'; $StarTemplate_Replace[] = '<?\\1\\2?>'; } /* 此类编译的语法 _if _elseif _else _for _while _foreach _eval _echo _print_r _变量输出 */ $StarTemplate_Preg[] = '/'.$_Left.'(else if|elseif) (.*?)'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left.'for (.*?)'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left.'while (.*?)'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left.'(loop|foreach) (.*?)'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left.'if (.*?)'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left.'else'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left."(eval|_)( |[\r\n])(.*?)".$_Right.'/is'; $StarTemplate_Preg[] = '/'.$_Left.'_e (.*?)'.$_Right.'/is'; $StarTemplate_Preg[] = '/'.$_Left.'_p (.*?)'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left.'\/(if|for|loop|foreach|eval|while)'.$_Right.'/i'; $StarTemplate_Preg[] = '/'.$_Left.'((( *(\+\+|--) *)*?(([_a-zA-Z][\w]*\(.*?\))|\$((\w+)((\[|\()(\'|")?\$*\w*(\'|")?(\)|\]))*((->)?\$?(\w*)(\((\'|")?(.*?)(\'|")?\)|))){0,})( *\.?[^ \.]*? *)*?){1,})'.$_Right.'/i'; $StarTemplate_Preg[] = "/( | ){0,}(\r\n){1,}\";/"; $StarTemplate_Preg[] = '/'.$_Left.'(\#|\*)(.*?)(\#|\*)'.$_Right.'/'; $StarTemplate_Preg[] = '/'.$_Left.'\%([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)'.$_Right.'/'; /* 编译为相应的PHP文件语法 _所产生错误在运行时提示 */ $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = ''; $StarTemplate_Replace[] = 'lang_array[\'\\1\'];?>'; /* 在有必要时 开启 */ //ksort($StarTemplate_Preg); //ksort($StarTemplate_Replace); /* 执行正则分析编译 */ $StarTemplate_Conver=preg_replace($StarTemplate_Preg,$StarTemplate_Replace,$StarTemplate_Conver); /* 过滤敏感字符 */ $StarTemplate_Conver = str_replace(array('!'.$this->arrayConfig['right_tag'],'!'.$this->arrayConfig['left_tag'],'?>arrayConfig['right_tag'],$this->arrayConfig['left_tag'],''),$StarTemplate_Conver); /* 整理输出缓存内容 */ if ($Global_var_out) { $StarTemplate_Conver = "\r\n".$StarTemplate_Conver; } $this->template_write($_PATH['Save'],$StarTemplate_Conver); /* End conver; */ /* ***************模板进行相关编译结束******************** */ return $_PATH['Save']; } /* 类错误信息输出 */ private function StarTemplate_Error($Msg) { echo $Msg; /*exit;*/ } /* 清理缓存输出 或缓存 */ public function StarTemplate_clean($type = 'cache') { switch ($type) { /* 判断是否是输出缓存 */ case 'cache': $_PATH = dirname($this->get_Template_Cache_Path('_')); $_END = $this->arrayConfig['templateCacheExt']; $_PATH_ = glob($_PATH.'/*'.$_END); break; /* 判断是否是模板缓存 */ case 'compile': $_PATH = dirname($this->get_Template_Compile_Path('_')); $_END = $this->arrayConfig['templateCompileExt']; $_PATH_ = glob($_PATH.'/*'.$_END); break; } /* 判断是否是输出缓存 */ if (!empty($type) && empty($_PATH)) { echo $_PATH = $this->get_Template_Cache_Path($type, true); $_PATH_ = glob($_PATH); } if ($_PATH_) { if (is_array($_PATH_)) { $j = 0; foreach ($_PATH_ as $val) { if (file_exists($val)) { unlink($val); $j ++; } } return $j; }else{ return false; } } return false; } /* 获取实时模板引擎运行时间 */ public function template_Runtime() { /* 返回执行时间 */ return $this->arrayConfig['Runtime'] = round($this->getMicrotime() - $this->arrayConfig['Runtime'],5); } /* 释放资源 */ public function __destruct() { $this->arrayConfig = null; } //类结束 } class StarTemplate_debug { private $thiss = null; /* 类实例化($this) */ public function __construct($thiss) { $this->thiss = $thiss; } /* 模板错误输出 */ public function StarTemplate_xError($_StarTemplate_error) { /* 获取最后一次错误记录 */ $_StarTemplate_error_ = error_get_last(); $_StarTemplate_error = array(); /* 判断是否重要错误信息 */ switch ($_StarTemplate_error_['type']) { case 1: $_StarTemplate_error['type'] = $this->thiss->StarTemplate_Class_Lang[3]; case 2: $_StarTemplate_error['type'] = $this->thiss->StarTemplate_Class_Lang[4]; case 4: $_StarTemplate_error['type'] = $this->thiss->StarTemplate_Class_Lang[5]; default: $_StarTemplate_error['type'] = '1'; } /* 错误信息格式化 */ if ($_StarTemplate_error['type']) { $_StarTemplate_error['body'] = file($_StarTemplate_error_['file']); $_StarTemplate_error['err_'] = "\r\n"; $_StarTemplate_error['err_'] .= "[StarTemplate]