phpnew模板引擎类

<?php
/*
# @category: 分享工作室;
# @copyright: 分享在线传媒公社;
# @var; PHPnew.class ;
# @version: PHPnew 7.0 Professional;
*/
//模板引擎解析类;
class PHPnew 
{
	const PHP = 5;						//PHP限制版本;
	public $templates_dir = 'Templates/default/'; 			//模板路径;
	public $templates_cache = 'Data/cache_tpl/'; 		//缓存模板路径;
	public $templates_default = 'Templates/default/'; 		//默认模板路径;
	public $templates_new = true; 							//设置当次更新;
	public $templates_time = 360;				//过期时间,分钟计算;
	//以下的默认设置
	public $templates_charset = 'utf-8';
	public $templates_postfix = '.html'; 		//模板后缀;
	public $templates_auto = true;				//自动更新模板;
	public $templates_caching = '.php';			//缓存后缀;
	public $templates_debug = array();			//错误信息;
	public $templates_lonlabel = true;			//长标签;
	public $templates_space = false;			//清除无意义字符
	public $templates_php = false;				//为每个缓存头部增加PHP码;
	//结果集;
	public $templates_file = array();					//模板文件
	public $templates_cache_file = null;          		//缓存文件;
	public $templates_name = null;						//标识名
	public $templates_message = null;					//html内容;
	public $templates_update = 0;						//更新次数
	public $templates_assign = array();					//用户用smarty模式;
	public $PHPnew = 'PHPnew 7.0 Professional';
	//缓存控制;
	public $templates_menu = array();					//用于记录每个模板信息;
	public $templates_replace = array();				//用于智能更新,可以将模板中的内容直接替换;
	//构造函数
	public function __construct()
	{
		// 确认php版本,低过设置的, 就提供一下debug出去。但不终止。
		if((int) phpversion() < self::PHP)
		$this->templates_debug[] = 'PHP version is too low ' .self::PHP;
		//为属性作初级判断;
		$this->templates_auto = (boolean) $this->templates_auto;
		$this->templates_lonlabel = (boolean) $this->templates_lonlabel;
		$this->templates_space = (boolean) $this->templates_space;
		$this->templates_new = (boolean) $this->templates_new;

		//禁止默认模板目录不存在
		is_dir($this->templates_default) === false && exit('error templates_default');

		//为控制设置流程,先引入配置文件, 里面记录着所有缓存文件的时间。
		if(is_file($this->templates_cache.'templates_caceh.php') && $this->templates_auto===true)
		$this->templates_menu = include($this->templates_cache.'templates_caceh.php');
	}
	
	//解析开始;
	public function display($file_name){
		// 初始化先设置变量信息
		$var_list = $this->parse_var();
		//取得路径;
		$this->templates_file[$file_name] = $this->get_path($file_name);
		//取得文件名字;
		$this->templates_name = $file_name;

		//取得缓存路径;
		$this->templates_cache_file[$file_name] = $this->get_path();
		
		// 如果不自动更新,就直接调用缓存。
		if($this->templates_auto===false){
			return $this->view($this->templates_cache_file[$file_name]);
		}
		
		//如果设置了当次更新,就将配置数组清空.
		if($this->templates_new===true){
			$this->templates_menu = array();
		}
		
		//判断一下文件是否存在。 是否已经过期,然后生成并且显示。
		if($this->check($this->templates_name)===true){
			return $this->view($this->templates_cache_file[$file_name]);
		}

		$this->templates_message = null;
		if(is_file($this->templates_file[$this->templates_name]) == true)
		$this->templates_message = $this->replace_html(file_get_contents($this->templates_file[$this->templates_name],LOCK_EX));
		
		$this->templates();
		return	$this->view($this->fileplus());
	}

	//显示出来;
	private function view($path_php){
		//释放数组内容。
		if(empty($this->templates_assign) === false)
			extract($this->templates_assign,EXTR_OVERWRITE);
		if(is_file($path_php) === true){
			include($path_php);
		}else {
			print $path_php.' Does not exist<br>';
		}
		return true;
	}

	private function parse_var(){
		static $var_list;
		if(empty($var_list) === true){ 
			$list = array();
			foreach ($GLOBALS as $key => $val)
			{
				$list[$key] = $val;
			}
			$var_list = $list;
			foreach ($var_list as $phpnew_key =>$phpnew_value){
				$this->assign($phpnew_key,$phpnew_value);
			}
		}
		return $this->templates_assign;
	}
	//生成缓存
	private function fileplus()
	{
		file_put_contents($this->templates_cache_file[$this->templates_name],$this->templates_message,LOCK_EX);
		$this->templates_message = array();
		return $this->templates_cache_file[$this->templates_name];
	}

	//控制配置
	private function templates(){
		if(empty($this->templates_menu[$this->templates_name]) === false)
		unset($this->templates_menu[$this->templates_name]);
		if(is_array($this->templates_menu)===false)
		$this->templates_menu = array();
		if(is_file($this->templates_file[$this->templates_name]) == true)
		$this->templates_menu[$this->templates_name] = md5_file($this->templates_file[$this->templates_name]);

		if(($php = null) && empty($this->templates_php) === false)
		$php = $this->templates_php."\r\n";
		file_put_contents($this->templates_cache.'templates_caceh.php',
		sprintf($php."<?php \r\n return %s;",var_export($this->templates_menu,true)),LOCK_EX);
	}

	//路径处理
	private function get_path($file_name=null){
		//为默认路径做完整路径抓取;
		$this->path();
		if($file_name!==null){
			$file_all = $this->templates_dir.$file_name.$this->templates_postfix;
			if($this->templates_dir===null || is_file($file_all)===false){
				$file_all = realpath($this->templates_default).DIRECTORY_SEPARATOR.$file_name.$this->templates_postfix;
			}
			if(is_file($file_all)===false){
				return false;
				$this->templates_debug[] = 'Template file does not exist or an error';
			}
			return (string) $file_all;
		}else {
			$file = $this->templates_file[$this->templates_name];
			$file_arr = pathinfo($file);
			$postfix = basename(dirname($file));
			return $this->templates_cache.$postfix.'_'.$this->templates_name.'_cache'.$this->templates_caching;
		}
		return false;
	}
	// 路径规范处理;
	private function path(){
		$this->templates_dir = realpath(strtr($this->templates_dir,array('./'=>'','//'=>'/','\\\\'=>'\\'))).DIRECTORY_SEPARATOR;
		$this->templates_cache = realpath(strtr($this->templates_cache,array('./'=>'','//'=>'/','\\\\'=>'\\'))).DIRECTORY_SEPARATOR;
		// 不能判断目录是否存在, 因为还有默认目录功能。
		if(strlen($this->templates_dir)<=2)
		exit('Catalog Error');
		if(strlen($this->templates_cache)<=2)
		exit('Catalog Error');
	}
	//控制判断
	private function check($name){
		//对文件及目录判断
		if(strlen($this->templates_name)===0){
			$this->templates_name = 'index';
		}

		// 检查默认模板目录是否存在
		if(is_dir($this->templates_dir)===false){
			exit('Templates directory does not exist');
		}
		// 检查缓存模板目录是否存在
		if(is_dir($this->templates_cache)===false){
			exit('Template cache directory does not exist');
		}

		// 判断缓存文件是否存在,不存在就报错.
		if(is_file($this->templates_file[$name])===false){
			exit('Template does not exist: '.$name);
		}
		// true 让判断成真,即返回缓存文件 // false 将执行编译;
		if(empty($this->templates_menu)===true)
		return false;

		if(time() - fileatime($this->templates_cache.'templates_caceh.php')>=$this->templates_time*60){
			if(is_file($this->templates_cache.'templates_caceh.php') === true)
			unlink($this->templates_cache.'templates_caceh.php');
			return false;
		}
		if(empty($this->templates_menu[$name]) === false && md5_file($this->templates_file[$name])===$this->templates_menu[$name]){
			return true;
		}

		return false;
	}

	//假如用户用强制性;
	public function assign($phpnew_var,$phpnewvalue=null){
		$php_key = $php_val = null;
		if($phpnew_var=='')
		return false;
		if(is_array($phpnew_var)===true){
			foreach ($phpnew_var as $php_key => $php_val){
				if(is_array($php_val)===true){
					$this->assign($php_val);
				}
				if(is_numeric($php_key)===false || $php_key{0}!='_')
				$this->templates_assign[$php_key] = $php_val;
			}
		}else {
			if(is_numeric($phpnew_var)===false || $phpnew_var{0}!='_')
			$this->templates_assign[$phpnew_var] = $phpnew_value;
		}
	}

	//替换函数;
	protected function replace_html($template){
		//替换
		$template = preg_replace(
		"/[\n\r\t]*\{templatesub\s+(.+)\}[\n\r\t]*/iseU",
		"\$this->get_contents('$1')",
		$template
		);
		//直接输出php
		$template = preg_replace('/[\n\r\t]*\<\?php.*\\?\>[\n\r\t]*/iseU',
		'\'[php]\'.base64_encode(\'$0\').\'[/php]\'',
		$template
		);

		//静态替换
		$template = preg_replace(
		"/[\n\r\t]*\{html\s+(.+?)\}[\n\r\t]*/ise",
		"\$this->get_var('$1')",
		$template
		);
		//替换模板载入命令
		$template = preg_replace(
		"/[\n\r\t]*\{template\s+\\$(.+)\}[\n\r\t]*/isU",
		'<? include display(-%-$1); ?>',
		$template
		);
		$template = preg_replace(
		"/[\n\r\t]*\{template\s+(.+)\}[\n\r\t]*/isU",
		"<? include display('$1'); ?>",
		$template
		);

		//过滤 <!--{}-->
		$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
		//替换 PHP 换行符
		$template = str_replace("{LF}", "<?=\"\\n\"?>", $template);
		//替换直接变量输出
		$varRegexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)"
		. "(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";
		$template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $template);
		$template = preg_replace("/$varRegexp/es", "\$this->addquote('<?=\\1?>')", $template);
		$template = preg_replace("/\<\?\=\<\?\=$varRegexp\?\>\?\>/es", "\$this->addquote('<?=\\1?>')", $template);
		//替换语言包变量
		$template = preg_replace("/\{lang\s+(.+?)\}/is", "<?=\$language['\\1']?>", $template);
		//替换特定函数
		$template = preg_replace(
		"/[\n\r\t]*\{eval\s+(.+?)\}[\n\r\t]*/ies",
		"\$this->stripvtags('<? \\1; ?>','')",
		$template
		);
		$template = preg_replace(
		"/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies",
		"\$this->stripvtags('<? \\1; ?>','')",
		$template
		);
		$template = preg_replace(
		"/([\n\r\t]*)\{elseif\s+(.+?)\}([\n\r\t]*)/ies",
		"\$this->stripvtags('\\1<? } elseif(\\2) { ?>\\3','')",
		$template
		);
		$template = preg_replace(
		"/([\n\r\t]*)\{else\}([\n\r\t]*)/is",
		"\\1<? } else { ?>\\2",
		$template
		);
		//替换循环函数及条件判断语句
		for ($i = 0; $i < 6; $i++) {
			$template = preg_replace(
			"/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r]*(.+?)[\n\r]*\{\/loop\}[\n\r\t]*/ies",
			"\$this->stripvtags('<? if(is_array(\\1)) { foreach(\\1 as \\2) { ?>','\\3<? } } ?>')",
			$template
			);
			$template = preg_replace(
			"/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*(.+?)[\n\r\t]*\{\/loop\}[\n\r\t]*/ies",
			"\$this->stripvtags('<? if(is_array(\\1)) { foreach(\\1 as \\2 => \\3) { ?>','\\4<? } } ?>')",
			$template
			);
			$template = preg_replace(
			"/([\n\r\t]*)\{if\s+(.+?)\}([\n\r]*)(.+?)([\n\r]*)\{\/if\}([\n\r\t]*)/ies",
			"\$this->stripvtags('\\1<? if(\\2) { ?>\\3','\\4\\5<? } ?>\\6')",
			$template
			);
		}
		//常量替换
		$template = preg_replace(
		"/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s",
		"<?=\\1?>",
		$template
		);
		//删除 PHP 代码断间多余的空格及换行
		$template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template);

		//其他替换
		$template = preg_replace(
		"/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/e",
		"\$this->transamp('\\0')",
		$template
		);
		$template = preg_replace(
		"/\<script[^\>]*?src=\"(.+?)\".*?\>\s*\<\/script\>/ise",
		"\$this->stripscriptamp('\\1')",
		$template
		);
		$template = preg_replace(
		"/[\n\r\t]*\{block\s+([a-zA-Z0-9_]+)\}(.+?)\{\/block\}/ies",
		"\$this->stripblock('\\1', '\\2')",
		$template
		);
		$template = preg_replace('/[\n\r\t]*\[php\](.*)\[\/php\][\n\r\t]*/iseU','base64_decode(\'\\1\')',$template);
		$template = preg_replace('/<script.+script>/iseU','\'[script]\'.base64_encode(\'$0\').\'[/script]\'',$template);
		if ($this->templates_space===true) {
			$template = preg_replace(
			array('/\r\n/isU','/<<<EOF/isU'),array('',"\r\n<<<EOF\r\n"),$template);
		}
		$template = preg_replace('/[\n\r\t]*\[script\](.+)\[\/script\][\n\r\t]*/iseU','base64_decode(\'$1\')',$template);
		$template = strtr($template,array('-%-'=>'$','\"'=>'"','<style>'=>'<style type="text/css">','<script>'=>'<script type="text/javascript">'));
		if(empty($this->templates_php) === false)
		$template = $this->templates_php."\r\n".$template;

		$template = strtr($template,array('include display'=>'$this->display'));
		if($this->templates_lonlabel===true){
			$template = strtr($template,
			array('<?php'=>'<?','<?php echo'=>'<?='));
			$template = strtr($template,
			array('<?'=>'<?php ','<?='=>'<?php echo '));
		}
		$template = strtr($template,$this->templates_replace);
		$this->templates_update +=1;
		return (string) $template;
	}
	//模板引擎需要的函数. 开始.
	protected function get_contents($filename){
		$this->templates_file[$filename] = $this->get_path($filename);
		if(is_file($this->get_path($filename)) === true){
			$files = file_get_contents($this->templates_file[$filename],LOCK_EX);
			//替换
			$files = preg_replace(
			"/[\n\r\t]*\{templatesub\s+(.+)\}[\n\r\t]*/iseU",
			"\$this->get_contents('$1')",
			$files
			);
			return $files;
		}
		return false;
	}
	protected function get_var($phpnew_name){
		if(empty($this->templates_assign[$phpnew_name]) === false)
			return $this->templates_assign[$phpnew_name];
		return 'Static variable is not defined';
	}
	protected function transamp($template) {
		$template = str_replace('&', '&amp;', $template);
		$template = str_replace('&amp;amp;', '&amp;', $template);
		$template = str_replace('\"', '"', $template);
		return $template;
	}
	protected function stripvtags($expr, $statement) {
		$expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));
		$statement = str_replace("\\\"", "\"", $statement);
		return $expr . $statement;
	}

	protected function addquote($var) {
		return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
	}

	protected function stripscriptamp($s) {
		$s = str_replace('&amp;', '&', $s);
		return "<script src=\"$s\" type=\"text/javascript\"></script>";
	}

	protected function stripblock($var, $s) {
		$s = str_replace('\\"', '"', $s);
		$s = preg_replace("/<\?=\\\$(.+?)\?>/", "{\$\\1}", $s);
		preg_match_all("/<\?=(.+?)\?>/e", $s, $constary);
		$constadd = '';
		$constary[1] = array_unique($constary[1]);
		foreach($constary[1] as $const) {
			$constadd .= '$__' . $const  .' = ' . $const . ';';
		}
		$s = preg_replace("/<\?=(.+?)\?>/", "{\$__\\1}", $s);
		$s = str_replace('?>', "\n\$$var .= <<<EOF\n", $s);
		$s = str_replace('<?', "\nEOF;\n", $s);
		return "<?php\n$constadd\$$var = <<<EOF" . $s . "\nEOF;\n?>";
	}


	//删除缓存;
	public function cache_dele($path = null){
		if($path===null){
			$path = $this->templates_cache;
		}
		$file_arr = scandir($path);
		foreach ($file_arr as $val){
			if($val === '.' || $val === '..'){
				continue;
			}
			if(is_dir($path.$val)===true)
			$this->cache_dele($path.$val.'/');
			if(is_file($path.$val)===true && $val!=='index.html')
			unlink($path.$val);
		}
	}
	public function __destruct(){}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值