/*********************************************
* 程序名:Luhd 轻型php模板编译类
* 版本: v1.0.2
* php版本要求 php ver5.2.0 或以上
* 提供者 tyds qq382596765 email tyds1@
* msn: luhdok@
* 欢迎技术交流 欢迎索要使用手册
***********************************************/
// Luhd 轻型php模板编译类定义文件
// CodeIgniter 框架下打开以下语句
// if (! defined('BASEPATH')) exit('No direct script access allowed');
class Tydsparser {
var $left_delimiter = '{';
var $right_delimiter = '}';
var $template_dir = 'microtpl';
var $compile_dir = 'cache';
var $html_dir = 'cache/html';
var $force_compile = false;
var $force_html =false;
var $exp_time = 0;
var $html_time = 0;
var $d_time=0;
var $ftpl_var = array();
var $starttime =0.00;
var $char_code_re = '';
public function __construct($config = array()){
$this->initialize($config);
// CodeIgniter 框架下打开以下语句
// log_message('debug', "Tydsparser Class Initialized");
}
private function initialize($config = array())
{
$path_parts = pathinfo(__FILE__);
$basedir = $path_parts["dirname"] ;
clearstatcache();
if (count($config) > 0)
{
if(!empty($config['left_tag'])&&!empty($config['right_tag'])){
$this->left_delimiter=$config['left_tag'];
$this->right_delimiter=$config['right_tag'];
}
if (!empty($config['template_dir'])){
$this->template_dir=THEROOT.$config['template_dir'];
}else{$this->template_dir=THEROOT.$this->template_dir;}
if (!empty($config['compile_dir'])&&!empty($config['html_dir']))
{
$this->compile_dir=THEROOT.$config['compile_dir'];
$this->html_dir=THEROOT.$config['html_dir'];
}else{
$this->compile_dir=THEROOT.$this->compile_dir;
$this->html_dir=THEROOT.$this->html_dir;
}
if (!empty($config['exp_time'])&&preg_match('/\d+/', $config['exp_time']))
{
$this->exp_time=$config['exp_time'];
}
if (!empty($config['html_time'])&&preg_match('/\d+/', $config['html_time']))
{
$this->exp_time=$config['html_time'];
}
if (!empty($config['datestr'])){
date_default_timezone_set(PRC);
$Dstrp = '/^\s*([1-9]\d{3})\s*[\-]?\s*(0?[1-9]|1[0-2])?\s*[\-]?\s*([0-2]?\d|3[01])?\s*([0-1]?\d|2[0-3])?\s*[:]?\s*([0-5]?\d)?\s*[:]?\s*([0-5]?\d)?$/';
if (preg_match($Dstrp,$config['datestr'],$time_arr)){
list($all, $Y,$M,$d,$H,$m,$S) = $time_arr;
$nowstr = date("Y-m-d H:i:s");
preg_match($Dstrp ,$nowstr,$now_arr);
list($alln, $Yn,$Mn,$dn,$Hn,$mn,$Sn) = $now_arr;
$Y=is_null($Y)?$Yn:$Y;
$M=is_null($M)?$Mn:$M;
$d=is_null($d)?$dn:$d;
$H=is_null($H)?$Hn:$H;
$m=is_null($m)?$mn:$m;
$S=is_null($S)?$Sn:$S;
$ms = mktime($H,$m,$S,$M,$d,$Y);
$this->d_time=$ms;
}
}
}
$re["gbk"] = "[\x20-\x7e]|[\x81-\xfe][\x40-\xfe]";
$re["gb2312"] = "[\x20-\x7e]|[\xb0-\xf7][\xa0-\xfe]";
$re["utf8"] = "[\x20-\x7e]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}";
$re["big5"] = "[\x20-\x7e]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])";
$this->char_code_re = $re["utf8"];
$this->create($this->compile_dir);
$this->create($this->html_dir);
}
public function __destruct(){
unset($this->_section,$this->ftpl_var);
}
private function mysubstr($str, $strlen, $suffix='') {
preg_match_all( '/'.$this->char_code_re.'/', $str, $match);
if(count($match[0]) <= $strlen) return $str;
$slice = join("",array_slice($match[0], 0, $strlen));
$slice = $slice.$suffix;
return $slice;
}
public function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
private function var_or_value($equalvalue)
{
$equalvalue = trim($equalvalue);
if(preg_match('/^\$\w([\w\[\]\$]*[\w\]])*/',$equalvalue))
{return $this->parse_vars($equalvalue); }
elseif(preg_match('/^[\'](.+)[\']$/',$equalvalue,$matches))
{return $equalvalue; }
elseif(preg_match('/^["](.+)["]$/',$equalvalue,$matches))
{ return $equalvalue; }
elseif(preg_match('/^\d+$/',$equalvalue,$matches))
{return $equalvalue; }
elseif(strtolower($equalvalue) == "true" || strtolower($equalvalue) == "false" || strtolower($equalvalue) == "null")
{return $equalvalue; }
elseif(strlen($equalvalue) == 0)
{return "''"; }
else{
$equalvalue =str_replace("\'", "'", $equalvalue);
$equalvalue ="'".str_replace("'", "\'", $equalvalue)."'";
return $equalvalue; }
}
protected function create($dir){
if (!is_dir($dir))
{
$temp = explode('/',$dir);
$cur_dir = '';
for($i=0;$i {
$cur_dir .= $temp[$i].'/';
if (!is_dir($cur_dir))
{
@mkdir($cur_dir,0777);
@fopen("$cur_dir/index.htm","a");
}
}
}
}
private function write_file($file_name,$content){
$compiledfile_url = $this->get_compiledfile_url($file_name);
if(!is_dir($this->compile_dir)){
$this->create($this->compile_dir);
}
if(!is_writable($this->compile_dir)){
$this->show_messages("请先将编译文件夹".$this->compile_dir."和该文件夹中的所有文件的属性改成777。");
}
$fp = fopen($compiledfile_url,'wb');
fwrite($fp,$content);
fclose($fp);
chmod($compiledfile_url,0777);
}
public function show_messages($message){
echo $message;
exit;
}
public function assign($vars,$value=null){
if(is_array($vars)){
foreach($vars as $key => $val){
if($key != ''){
$this->ftpl_var[$key] = $val;
}
}
}
else{
if(is_string($vars) && $vars != ''){
$this->ftpl_var[$vars] = $value;
}else
{$this->show_messages('assign()函数和 {assign...}模板语句里,
第一个参数必须是数组或字符串类型');}
}
}
public function display($file_name, $in_ci=false){
$this->starttime = $this->microtime_float();
error_reporting(E_ALL ^ E_NOTICE);
$show_content = $this->fetch($file_name);
if ($in_ci){
$CI =& get_instance();
$CI->output->append_output($show_content);
}else{
echo($show_content );
}
}
private function fetch($file_name){
$compiledfile_url = $this->get_compiledfile_url($file_name);
ob_start();
$this->compile($file_name);
include($compiledfile_url);
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function to_html($filename,$addname="",$pagenumber=1, $in_ci=false){
$this->starttime = $this->microtime_float();
$compiledfile_url = $this->get_compiledfile_url($filename);
$this->compile($filename);
if(!$this->is_html($filename,$addname,$pagenumber)){
ob_start();
if (!empty($addname))$filename.="_".$addname;
if ($pagenumber>1)$filename.="_".$pagenumber;
$fn=$this->get_html_url($filename);
include($compiledfile_url);
$fs=fopen($fn,'wb');
fwrite($fs,ob_get_contents());
fclose($fs);
ob_clean();
chmod($fn,0777);
}else{
if (!empty($addname))$filename.="_".$addname;
if ($pagenumber>1)$filename.="_".$pagenumber;
}
if ($in_ci){
ob_start();
include($this->get_html_url($filename));
$content = ob_get_contents();
ob_end_clean();
$CI =& get_instance();
$CI->output->append_output($content);
}else{
include($this->get_html_url($filename));
}
}
public function get_html($filename,$addname="",$pagenumber=1, $in_ci=false){
$this->starttime =$this->microtime_float();
if ($this->is_compiled($filename) && $this->is_html($filename,$addname,$pagenumber)) {
if (!empty($addname))$filename.="_".$addname;
if ($pagenumber>1)$filename.="_".$pagenumber;
if ($in_ci){
ob_start();
include($this->get_html_url($filename));
$content = ob_get_contents();
ob_end_clean();
$CI =& get_instance();
$CI->output->append_output($content);
}else{
include($this->get_html_url($filename));
exit;
}
}else{
$this->force_html=1;
}
}
public function outtime(){
$end=$this->microtime_float();
if ($this->starttime>0)
{$outtime = number_format(($end-$this->starttime)*1000,1);
$showstr = '编译时间为:'.number_format(($end-$this->starttime)*1000,1).'毫秒';
return $outtime;
}
return 0;
}
public function empty_vars(){
$this->ftpl_var = array();
return true;
}
protected function get_sourcefile_url($file_name){
return preg_match('/\/$/',$this->template_dir)?$this->template_dir.$file_name:$this->template_dir.'/'.$file_name;
}
protected function get_compiledfile_url($file_name){
return preg_match('/\/$/',$this->compile_dir)?$this->compile_dir.$file_name.'.php':$this->compile_dir.'/'.$file_name.'.php';
}
protected function get_html_url($file_name){
return preg_match('/\/$/',$this->html_dir)?$this->html_dir.$file_name.'.html':$this->html_dir.'/'.$file_name.'.html';
}
public function _quote($val){
return preg_quote($val,'/');
}
protected function is_compiled($file_name){
if($this->force_compile){
return false;
}
else{
$sourcefile_url = $this->get_sourcefile_url($file_name);
$compiledfile_url = $this->get_compiledfile_url($file_name);
if(!file_exists($compiledfile_url) || filemtime($sourcefile_url) > filemtime($compiledfile_url)){
clearstatcache();
return false;
}
elseif($this->exp_time && time()-filemtime($compiledfile_url)>$this->exp_time){
clearstatcache();
return false;
}
else {
clearstatcache();
return true;
}
}
}
protected function is_html($file_name,$addname='',$pagenumber=1){
if($this->force_html){
return false;
}
else{
$html_name=(empty($addname))?$file_name:$file_name."_".$addname;
$html_name=($pagenumber>1)?$html_name."_".$pagenumber:$html_name;
$compiledfile_url = $this->get_compiledfile_url($file_name);
$html_url=$this->get_html_url($html_name);
if(!file_exists($html_url) || (filemtime($html_url) < filemtime($compiledfile_url))){
clearstatcache();
return false;
}
elseif($this->html_time && time()-filemtime($html_url)>$this->html_time){
clearstatcache();
return false;
}
elseif ($this->d_time && $this->d_time > filemtime($html_url)){
clearstatcache();
return false;
}
else{
clearstatcache();
return true;
}
}
}
protected function compile($file_name){
$content = $this->get_contents($file_name);
$content = $this->parse_include($content);
if(!$this->is_compiled($file_name)){
$content = $this->parse_assign($content);
$content = $this->parse_variable($content);
$content = $this->parse_include_php($content);
$content = $this->parse_php($content);
$content = $this->parse_code($content);
$content = $this->parse_if($content);
$content = $this->parse_elseif($content);
$content = $this->parse_else($content);
$content = $this->parse_section($content);
$content = $this->parse_sectionelse($content);
$content = $this->parse_foreach($content);
$content = $this->parse_foreachelse($content);
$content = $this->parse_cycle($content);
$content = $this->parse_html($content);
$content = $this->parse_end($content);
$content = $this->parse_substr($content);
$content = $this->parse_note($content);
$thepathinfo = pathinfo(__FILE__);
$pluginsdir=$thepathinfo["dirname"].'/plugins';
if (is_dir($pluginsdir))
{
if ($dh = @opendir($pluginsdir)) {
while (($filenm = readdir($dh)) !== false ) {
if( $filenm !='.' AND $filenm !='..'){
$plugin_content = file_get_contents($pluginsdir.'/'.$filenm);
$check_regular = '/if\s*\(\s*!function_exists\s*\(\s*\'\w+\'\s*\)\s*\)\s*\{\s*function\s*(\w+)\s*\(\$content\s*,\s*&\$parser\s*\)\s*\{[\s\S]*?return\s*\$content;\s*\}\s*\}\s*/i';
if(preg_match_all($check_regular,$plugin_content,$plugin_arr)){
$funtion_arr = $plugin_arr[1];
include_once($pluginsdir.'/'.$filenm);
foreach ($funtion_arr as $value){
$backcontent = call_user_func($value, $content,$this);
if (is_string($backcontent)){$content =$backcontent; }
}
}
}
}
closedir($dh);
}
}
$this->write_file($file_name,$content);
}
}
private function get_contents($file_name){
$sourcefile_url = $this->get_sourcefile_url($file_name);
if(!file_exists($sourcefile_url) || !($content = file_get_contents($sourcefile_url))) {
$this->show_messages("无法读取模板文件{$file_name},请检查文件是否存在。");
}
return $content;
}
// 模板语言例句:{code} $mm = 1; {/code}
protected function parse_code($content){
$code_regular = '/'.$this->_quote($this->left_delimiter).'code'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/code'.$this->_quote($this->right_delimiter).'/is';
if(preg_match_all($code_regular,$content,$code_arr)){
$content = preg_replace($code_regular,'',$content);
$ext_arr = $code_arr[1];
foreach ($code_arr[1] as $key=>$value){
if(preg_match_all('/\$\w(?:[\w\[\]\$]*[\w\]])*/',$value,$code_arr1)){
foreach ($code_arr1[0] as $key1 => $value1){
$ext_arr[$key] = preg_replace('/'.$this->_quote($value1).'/',$this->parse_vars($value1),$ext_arr[$key],1);
}
$content = preg_replace('/'.$this->_quote($code_arr[1][$key]).'/',$ext_arr[$key],$content,1);
}
}
}
return $content;
}
// 模板语言例句: {php} $mm = 1; {/php}
protected function parse_php($content){
$php_regular = '/'.$this->_quote($this->left_delimiter).'php'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/php'.$this->_quote($this->right_delimiter).'/is';
$content = preg_replace($php_regular,"",$content);
return $content;
}
protected function parse_vars($vars){
$old_vars =$vars;
$vars = preg_replace('/[\$]+/','$',$vars);
$vars = preg_replace('/[\'"]+/','',$vars);
$vars = preg_replace('/(\[\])+/','',$vars);
$vars = preg_replace('/(\[\w+)\[/','\1][',$vars);
$vars = preg_replace('/\](\w+\])/','][\1',$vars);
$vars = preg_replace('/\](\w+)\[/','][\1][',$vars);
if(preg_match('/\$[\]\[]/',$vars)){$this->show_messages("模板变量$old_vars格式错误,\$后要有变量名。解析".$old_vars."时出错");}
$vars = preg_replace('/\$(\w+)/','$this->ftpl_var[\'\1\']',$vars);
$vars = preg_replace('/\[(\w+)\]/','[\'\1\']',$vars);
if (strpos($vars, "['section']") === false){
eval('if(!isset('.$vars.')) $xx="no"; unset($xx);');
}
return $vars ;
}
// 模板语言例句:{$xxx[xxx]} {$xxx[$xxx]} {$xxx[$xxx[aaa]]}
protected function parse_variable($content){
$variable_regular = '/'.$this->_quote($this->left_delimiter).'(\$\w(?:[\w\[\]\$]*[\w\]])*)'.$this->_quote($this->right_delimiter).'/';
if(preg_match_all($variable_regular,$content,$variable_arr)){
foreach ($variable_arr[1] as $key=>$value){
$value = $this->parse_vars($value);
$replacestr = $value;
if (preg_match('/^\$\w(?:[\w\[\]\$]*[\w\]])*/',$value)) {
$realv ='';
if (strpos($value, "['section']") === false){
eval('if(isset('.$value.')) $realv = '.$value.';');
}
if(is_array($realv))
{
$value = var_export($realv,1);
$replacestr ='"'.str_replace(",)", ")", str_replace('"', '\"', str_replace("\n", "", $value))).'"' ;
}
elseif(is_bool($realv))
{
$replacestr =$realv?"'true'":"'false'" ;
}
}
$rep = " $rep .= $replacestr;
$rep .= ";?>";
$content = preg_replace('/'.$this->_quote($variable_arr[0][$key]).'/',$rep,$content,1);
}
}
return $content;
}
// 模板语言例句: {assign var="ll" value="vvv"}
protected function parse_assign($content){
$assign_regular ='/'.$this->_quote($this->left_delimiter).'assign\s+var\s*=\s*([\'"]?\w+[\'"])?\s+value\s*=\s*(.+?)'.$this->_quote($this->right_delimiter).'/';
if(preg_match_all($assign_regular,$content,$assign_arr)){
foreach ($assign_arr[0] as $key=>$value){
$varstr = $this->var_or_value($assign_arr[1][$key]);
$valuestr =trim($assign_arr[2][$key]);
$valuestr = $this->var_or_value($valuestr);
//eval("\$this->assign($varstr,$valuestr);");
$rep ='ftpl_var['.$varstr.'] = '.$valuestr.';?>';
/*$rep = "assign($varstr,$valuestr);?>";*/
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
}
}
return $content;
}
protected function _cycle($value){
$thevalue = $value;
static $cycle_index, $thevalue;
if(!isset($cycle_index)) $cycle_index = 0;
if($value !== $thevalue) $cycle_index = 0;
if(is_string($value))
{ $thevalue = $value;
$cycle_arr = explode(',',$value);
$cycle_value = $cycle_arr[$cycle_index];
if($cycle_index >= count($cycle_arr)-1) $cycle_index = 0;
else $cycle_index++;
return $cycle_value;
}else
{$this->show_messages('循环值必须是字符串类型');}
}
// 模板语言例句:{cycle values = "xxx"}
protected function parse_cycle($content){
$cycle_regular = '/'.$this->_quote($this->left_delimiter).'cycle\s+values\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|.+)'.$this->_quote($this->right_delimiter).'/iU';
if(preg_match_all($cycle_regular,$content,$cycle_arr))
{
foreach ($cycle_arr[0] as $key=>$value){
$cylevalue =$cycle_arr[1][$key];
$cylevalue = trim($cylevalue);
$cyclestr = $this->var_or_value($cylevalue);
$rep = "_cycle($cyclestr);?>";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
}
}
return $content;
}
protected function _html($html,$name,$options,$selected,$opt1,$opt2,$opt3){
if(!is_string($name)) {$this->show_messages('{html_...}语句的name值必须是字符串类型');}
if(!is_array($options)) {$this->show_messages('{html_...}语句的options值必须是数组');}
if(is_int($opt1)) $separator = $opt1;
elseif(is_int($opt2)) $separator = $opt2;
elseif(is_int($opt3)) $separator = $opt3;
else $separator = 0;
if(strtolower($opt1)=='left' OR strtolower($opt1)=='right' ) $labelposition = $opt1;
elseif(strtolower($opt2)=='left' OR strtolower($opt2)=='right' ) $labelposition = $opt2;
elseif(strtolower($opt3)=='left' OR strtolower($opt3)=='right' ) $labelposition = $opt3;
else $labelposition = 'right';
if(strtolower($opt1)=='disabled') $isdisabled = $opt1;
elseif(strtolower($opt2)=='disabled' ) $isdisabled = $opt2;
elseif(strtolower($opt3)=='disabled') $isdisabled = $opt3;
else $isdisabled = '';
switch ($html){
case 'options':
$select="";
if (is_array($options)){
foreach ($options as $key=>$value){
$isselected=($selected==$key)?'selected':'';
$select.="$value";
}
}
$select.="";
return $select;
break;
case 'checkboxes':
$i=1;$check='';$separator_out='';
if (is_array($options)){
foreach ($options as $key=>$value){
if ($separator>0) $separator_out=($i%$separator==0)?'
':'';
if (!is_array($selected) && !is_object($selected)) { settype($selected, 'array');};
$isselected=in_array($key,$selected)?'checked':'';
if($labelposition=="left")
{ $check.="$value $separator_out";
}else{
$check.="$value $separator_out";
}
$i++;
}
}
return $check;
break;
case 'radios':
$i=1;$check='';$separator_out='';
if (is_array($options)){
foreach ($options as $key=>$value){
if ($separator>0) $separator_out=($i%$separator==0)?'
':'';
$isselected=($selected==$key)?'checked':'';
if($labelposition=="left")
{ $check.="$value $separator_out";
}else{
$check.="$value $separator_out";
}
$i++;
}
}
return $check;
break;
}
}
/* 模板语言例句:
* {html_radios name=$aaa options=$adata checked=$checked separator=2 labelposition=left disabled}
* {html_checkboxes name=$aaa options=$adata selected=$checked separator=2}
* {html_options name=$aaa options=$adata selected=$checked separator=2}
**/
protected function parse_html($content){
$option_regular = '/'.$this->_quote($this->left_delimiter).'html_(\w+)\s+name\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+options\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*)(\s+(?:selected|checked)\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*))?((\s+(?:separator\s*=|labelposition\s*=)?\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)){0,3})\s*'.$this->_quote($this->right_delimiter).'/isU';
if(preg_match_all($option_regular,$content,$option_arr)){//print_r($option_arr);
foreach ($option_arr[0] as $key=>$value){
$name = $this->var_or_value($option_arr[2][$key]);
$options = $this->var_or_value($option_arr[3][$key]);
$selected = $this->var_or_value($option_arr[5][$key]);
$otherstr =ltrim(trim($option_arr[6][$key]));
if (strlen($otherstr) > 0){
$otherstr = preg_replace('/\s+/',',',$otherstr);
$othera = explode ( ',', $otherstr);
if(!isset($othera[1])){$othera[1] ='';$othera[2] ='';}
else{
if(!isset($othera[2])){$othera[2] ='';}
}
}else
{$othera[0] ='';$othera[1] ='';$othera[2] ='';}
$temparry = array();
foreach ($othera as $thekey=>$thevalue){
if(preg_match('/separator\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)/',$thevalue,$matches)){
$temparry[] = $this->var_or_value($matches[1]);
unset($matches);
}
elseif(preg_match('/labelposition\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)/',$thevalue,$matches)){
$temparry[] = $this->var_or_value($matches[1]);
unset($matches);
}
else{
$temparry[] = $this->var_or_value($thevalue);
}
}
$othera = $temparry;
unset($temparry);
switch ($option_arr[1][$key]){
case 'options':
$rep = "_html('".$option_arr[1][$key]."',".$name.",".$options.",".$selected.",".$othera[0].",".$othera[1].",".$othera[2].");\r\n?>";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
break;
case 'checkboxes':
$rep = "_html('".$option_arr[1][$key]."',".$name.",".$options.",".$selected.",".$othera[0].",".$othera[1].",".$othera[2].");\r\n?>";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
break;
case 'radios':
$rep = "_html('".$option_arr[1][$key]."',".$name.",".$options.",".$selected.",".$othera[0].",".$othera[1].",".$othera[2].");\r\n?>";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
break;
}
}
}
return $content;
}
// 模板语言例句:{if $cont.id > 0} 该语句和 {elseif ...}语句的里 条件部分除了会解析该部分里的模板变量外, 不会作任何修改, 所以需注意条件的合理性,文字意义的字符需要用引号包围。这点不同于其他语句。
protected function parse_if($content){
$if_regular = '/'.$this->_quote($this->left_delimiter).'if\s(.+)'.$this->_quote($this->right_delimiter).'/isU';
if(preg_match_all($if_regular,$content,$if_arr)){
foreach ($if_arr[0] as $key=>$value){
if(preg_match_all('/\$\w(?:[\w\[\]\$]*[\w\]])*/',$value,$if_arr1)){
foreach ($if_arr1[0] as $key1=>$value1){
$if_arr[1][$key] = preg_replace('/'.$this->_quote($value1).'/',$this->parse_vars($value1),$if_arr[1][$key],1);
}
$replacestr = str_replace('
$rep = "";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
}
else{
$replacestr = str_replace('
$rep = "";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
}
}
}
return $content;
}
// 模板语言例句: {elseif $action=='useradd_1'}
protected function parse_elseif($content){
$if_regular = '/'.$this->_quote($this->left_delimiter).'elseif\s(.+)'.$this->_quote($this->right_delimiter).'/isU';
if(preg_match_all($if_regular,$content,$if_arr)){
foreach ($if_arr[0] as $key=>$value){
if(preg_match_all('/\$\w(?:[\w\[\]\$]*[\w\]])*/',$value,$if_arr1)){
foreach ($if_arr1[0] as $key1=>$value1){
$if_arr[1][$key] = preg_replace('/'.$this->_quote($value1).'/',$this->parse_vars($value1),$if_arr[1][$key],1);
}
$replacestr = str_replace('
$rep = "";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
}
else{
$replacestr = str_replace('
$rep = "";
$content = preg_replace('/'.$this->_quote($value).'/',$rep,$content,1);
}
}
}
return $content;
}
// 模板语言: {else}
protected function parse_else($content){
$else_regular = '/'.$this->_quote($this->left_delimiter).'else'.$this->_quote($this->right_delimiter).'/i';
$rep = "";
$content = preg_replace($else_regular,$rep,$content);
return $content;
}
// 模板语言例句:{section name=xxx loop=$myloopvar start=3 step=2}
protected function parse_section($content){
$section_regular = '/'.$this->_quote($this->left_delimiter).'section\s+name\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+loop\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*)(\s+start\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|\d+))?(\s+step\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|\d+))?'.$this->_quote($this->right_delimiter).'/';
if(preg_match_all($section_regular,$content,$section_arr)){
foreach($section_arr[2] as $key=>$val){
$loopvar = $this->parse_vars($val);
$namevar = $this->var_or_value($section_arr[1][$key]);
$startvar = $this->var_or_value($section_arr[4][$key]);
$stepvar = $this->var_or_value($section_arr[6][$key]);
$basenamestr='$this->ftpl_var[\'section\']['.$namevar.']';
$rep = array();
$rep[] = " $rep[] = "if(!is_string($namevar)){\$this->show_messages('{section ...}语句的name值必须是字符串类型');}";
$rep[] = "\$start_value=is_int($startvar)?$startvar:0;";
$rep[] = "\$step_value =is_int($stepvar)?$stepvar:1;";
$rep[] = $basenamestr."['name'] =".$namevar.";";
$rep[] = $basenamestr."['start'] = \$start_value;";
$rep[] = $basenamestr."['step'] = \$step_value;";
$rep[] = $basenamestr."['loop'] = is_array({$loopvar})?count({$loopvar}):0;";
$rep[] = $basenamestr."['total'] = ceil((".$basenamestr."['loop']-".$basenamestr."['start'])/".$basenamestr."['step']);";
$rep[] = "if(".$basenamestr."['total'] > 0){";
$rep[] = " for(".$basenamestr."['index'] = ".$basenamestr."['start'], ".$basenamestr."['iteration'] = 1;";
$rep[] = " ".$basenamestr."['index']
$rep[] = " ".$basenamestr."['index'] += ".$basenamestr."['step'], ".$basenamestr."['iteration']++)";
$rep[] = " {";
$rep[] = " ".$basenamestr."['index_prev'] =".$basenamestr."['index'] - ".$basenamestr."['step'];";
$rep[] = " ".$basenamestr."['index_next'] = ".$basenamestr."['index'] +".$basenamestr."['step'];";
$rep[] = " ".$basenamestr."['first'] =(".$basenamestr."['iteration'] == 1);";
$rep[] = " ".$basenamestr."['last'] = (".$basenamestr."['iteration'] ==".$basenamestr."['total']);";
$rep[] = " ".$basenamestr."['rownum'] = ".$basenamestr."['iteration'];";
$rep[] = "?>";
$rs = implode("\r\n",$rep);
$content = preg_replace('/'.$this->_quote($section_arr[0][$key]).'/s',$rs,$content,1);
unset($rs);
}
}
return $content;
}
// 模板语言例句:{sectionelse}something{/section}
protected function parse_sectionelse($content){
$sectionelse_regular = '/'.$this->_quote($this->left_delimiter).'sectionelse'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/section'.$this->_quote($this->right_delimiter).'/is';
$content = preg_replace($sectionelse_regular,"\\1",$content);
return $content;
}
// 模板语言例句: {foreach name = myforeach1 key=foreachkey item=itemvalue from=$myarray}
protected function parse_foreach($content){
$foreach_regular = '/'.$this->_quote($this->left_delimiter).'foreach\s+(name\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+)?(key\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+)?item\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+[\'"]?)\s+from\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*)\s*'.$this->_quote($this->right_delimiter).'/';
if(preg_match_all($foreach_regular,$content,$foreach_arr)){
foreach($foreach_arr[6] as $key=>$val){
$from = $this->parse_vars($val);
$keystr = $this->var_or_value($foreach_arr[4][$key]);
if (preg_match('/^[\$\'"]\w+/',$keystr)) {
eval('if(is_string('.$keystr.') && strlen('.$keystr.") != 0 ){\$itemkey ='\$'.".$keystr .".' => ';}");
} else {
$itemkey = "''";
}
$namestr= $this->var_or_value($foreach_arr[2][$key]);
if (preg_match('/^[\$\'"]\w+/',$namestr)) {
eval('if(is_string('.$namestr.') && strlen('.$namestr.') != 0 ){$name =\'"\'.'.$namestr.'.\'"\';}');
} else {
$name = '';
}
$itemstr= $this->var_or_value($foreach_arr[5][$key]);
if (preg_match('/^[\$\'"]\w+/',$itemstr)) {
eval('if(is_string('.$itemstr.') && strlen('.$itemstr.") != 0 ){\$item ='\$'.".$itemstr.";}");
} else {
$this->show_messages('{foreach ...}语句的item值必须是字符串');
}
$rep = array();
$rep[] = ' $rep[]= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array');}";
if (strlen($name) !=0) {
$foreach_props = "\$this->ftpl_var['foreach'][$name]";
$rep[]= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);";
$rep[]= "if ({$foreach_props}['total'] > 0){";
$rep[]= " foreach (\$_from as $itemkey $item){";
$rep[]= " {$foreach_props}['iteration']++;";
$rep[]= " \$this->ftpl_var['foreach'][$name]['itemkey'] = ".substr($itemkey,0,strlen($itemkey)-4).";";
$rep[]= " \$this->ftpl_var['foreach'][$name]['item'] = $item;";
} else {
$rep[]= "if (count(\$_from)){";
$rep[]= " foreach (\$_from as $itemkey $item){";
$rep[]= " \$this->ftpl_var['foreach']['itemkey'] = ".substr($itemkey,0,strlen($itemkey)-4).";";
$rep[]= " \$this->ftpl_var['foreach']['item'] = $item;";
}
$rep[]= '?>';
$rs = implode("\r\n",$rep);
$content = preg_replace('/'.$this->_quote($foreach_arr[0][$key]).'/s',$rs,$content,1);
unset($rs,$name,$item,$from, $key1,$itemkey,$rep,$keystr, $itemstr,$namestr);
}
}
return $content;
}
// 模板语言例句:{foreachelse}something{/foreach}
protected function parse_foreachelse($content){
$sectionelse_regular = '/'.$this->_quote($this->left_delimiter).'foreachelse'.$this->_quote($this->right_delimiter).'(.+?)'.$this->_quote($this->left_delimiter).'\/foreach'.$this->_quote($this->right_delimiter).'/is';
$content = preg_replace($sectionelse_regular,"\\1",$content);
return $content;
}
// 模板语言: {/foreach} {/section} {/if}
protected function parse_end($content){
$section_end_regular = '/'.$this->_quote($this->left_delimiter).'\/section'.$this->_quote($this->right_delimiter).'/';
$section_rep = "";
$content = preg_replace($section_end_regular,$section_rep,$content);
$if_end_regular = '/'.$this->_quote($this->left_delimiter).'\/if'.$this->_quote($this->right_delimiter).'/';
$if_rep = "";
$content = preg_replace($if_end_regular,$if_rep,$content);
$if_end_regular = '/'.$this->_quote($this->left_delimiter).'\/foreach'.$this->_quote($this->right_delimiter).'/';
$if_rep = " unset(\$_form);
\r\n} ?>";
$content = preg_replace($if_end_regular,$if_rep,$content);
return $content;
}
// 模板语言例句:{include file = "xxx"} 当前目录是模板文件所在文件夹 因为该语句会编译模板文件, 再包含编译后的php文件, 所以, 这里只能是包含存储在设定的模板文件存储目录里的模板文件。 要包含其它文件, 请使用{include_php file = "xxx"} 语句
protected function parse_include($content){
$include_regular ='/'.$this->_quote($this->left_delimiter).'include\s+file\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?\w+\.*\w+[\'"]?)\s*'.$this->_quote($this->right_delimiter).'/iU';
if(preg_match_all($include_regular,$content,$include_arr)){
foreach ($include_arr[1] as $key => $value){
$valuestr = $this->var_or_value($value);
eval('if(!is_string('.$valuestr.') || strlen('.$valuestr.") == 0 ){\$this->show_messages('必须有模板文件名');}else{\$this->compile(".$valuestr."); }");
$content =preg_replace('/'.$this->_quote($include_arr[0][$key]).'/s',"",$content,1);
}
}
return $content;
}
// 模板语言例句:{include_php file = "xxx"} 当前目录是php缓冲文件所在文件夹,如果在这个文件夹或其子目录下找不到文件,就从网站根目录开始找.
protected function parse_include_php($content){
$include_php_regular ='/'.$this->_quote($this->left_delimiter).'include_php\s+file\s*=\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|[\'"]?[\w\.\/]+[\'"]?)\s*'.$this->_quote($this->right_delimiter).'/iU';
if(preg_match_all($include_php_regular,$content,$include_php_arr)){
foreach ($include_php_arr[1] as $key => $value){
$valuestr = $this->var_or_value($value);
eval('if(!is_string('.$valuestr.') || strlen('.$valuestr.") == 0 ){\$this->show_messages('文件名不正确.');}");
eval('if(file_exists(\''.$this->compile_dir.'\'."/".'.$valuestr.')){$thefilepath = \''.$this->compile_dir.'\'."/".'.$valuestr.';}else{$thefilepath = \''.THEROOT.'\'."/".'.$valuestr.';}');
$content =preg_replace('/'.$this->_quote($include_php_arr[0][$key]).'/s',"",$content,1);
}
}
return $content;
}
// 模板语言例句:{"下是三个html标签生成的模板语"|9...} 对文本值割尾输出
protected function parse_substr($content){
$substr_regular ='/'.$this->_quote($this->left_delimiter).'\s*(\$\w(?:[\w\[\]\$]*[\w\]])*|.+)\|(\d*)(\.{0,6})\s*'.$this->_quote($this->right_delimiter).'/iU';
if(preg_match_all($substr_regular ,$content,$substr_arr)){
foreach ($substr_arr[1] as $key => $value){
$valuestr = $this->var_or_value($value);
$substrlen= (int)$substr_arr[2][$key];
$suffix= "'".$substr_arr[3][$key]."'";
eval('if(!is_string('.$valuestr.') || strlen('.$valuestr.") == 0 ){echo '$value 值不是字符.'; \$temsub='".$substr_arr[0][$key]."X'; }else{\$temsub=\$this->mysubstr(".$valuestr.', '.$substrlen.' , '.$suffix.');}');
$content =preg_replace('/'.$this->_quote($substr_arr[0][$key]).'/s',$temsub,$content,1);
}
}
return $content;
}
// 模板语言例句:{* 我在服务端模板里, 你看不到} 模板里的注释语句, 优势是, 这样的注释客户端绝对看不到
protected function parse_note($content){
$note_regular ='/'.$this->_quote($this->left_delimiter).'\*.+'.$this->_quote($this->right_delimiter).'/iU';
if(preg_match_all($note_regular ,$content,$note_arr)){
foreach ($note_arr[0] as $key => $value){
$valuestr ='';
$content =preg_replace('/'.$this->_quote($note_arr[0][$key]).'/s',$valuestr,$content,1);
}
}
return $content;
}
}