欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

PHP 实现简单的模板引擎

程序员文章站 2022-04-30 08:49:25
...
模板引擎作为视图层和模型曾分离的一种解决方案。

首先我们新建一个Template.class.php 的文件

 '.m', 			//设置模板文件		'templateDir' => 'template/', 	//设置模板所在的文件夹		'compileDir'  => 'cache',		'debug'      => false,		//设置编译后存放的目录		'cache_htm'	  =>  true,		//是否需要编译成静态的html文件		'suffix_cache'=> '.htm',		//编译后的文件后缀			'cache_time'  =>2000,			// 多长时间自动更新		'php_turn'    =>false,			//是否支持原生的php代码		'cache_control' => 'control.dat',		);			private $compileTool;		//编译器	public $filename;		//模板文件名称	private $value =array();		//值栈	static private $instance  = null;		public $debug = array();	//调试信息	public function __construct($arrayConfig =array()){	        //返回当前UNIX时间戳和微妙数		$this->debug['begin'] = microtime(true);		$this->arrayConfig =$arrayConfig+$this->arrayConfig;		$this->getPath();		if(!is_dir($this->arrayConfig['templateDir'])){			exit("template isnt not found");		}		if(!is_dir($this->arrayConfig['compileDir'])){						mkdir($this->arrayConfig['compileDir'],0770,true);		}	include("Compile.class.php");		//$this->compileTool = new Compile;	}	/**				路径处理为绝对路径		*/	public function getPath(){		$this->arrayConfig['templateDir'] = strtr(realpath($this->arrayConfig['templateDir']),'\\','/').'/';		$this->arrayConfig['compileDir'] = strtr(realpath($this->arrayConfig['compileDir']),'\\','/').'/';	}		/***				单例模式获取模板的实例	**/	public static function getInstance(){		if(is_null(self::$instance)){			self::$instance = new Template();		}		return self::$instance;	}		public function setConfig($key,$value = null){		if(is_array($key)){			$this->arrayConfig = $key+$this->arrayConfig;		}else{			$this->arrayConfig[$key] = $value;		}	}	public function getConfig($key = null){		if($key){			return $this->arrayConfig[$key];		}else{			return $this->arrayConfig;		}			}		/**		    注入单个变量	**/	public function assign($key,$value){		$this->value[$key] = $value;	}		/**	    注入多个变量	**/	public function assignArray($array){		if(is_array($array)){				foreach($array as $k => $v){					$this->value[$k] = $v;				}						}	}	/***	        获取模板文件的路径		**/		public function path(){		return $this->arrayConfig['templateDir'].$this->filename.$this->arrayConfig['suffix'];	}	/***			是否需要缓存	**/	public function needCache(){		return $this->arrayConfig['cache_htm'];	}		/***				是否需要重新生成缓存文件	**/		public function reCache($file){		$flag = false;		//生成缓存文件		$cacheFile = $this->arrayConfig['compileDir'].md5(@$filename).'.'.'php';		//var_dump($cacheFile);		if($this->arrayConfig['cache_htm']===true){				//设置timeflag (判断当前时间-模板文件上次修改的时间)是否小于设置的缓存时间		//如果小于则返回TRUE					$timeFlag = (time()-@filemtime($cacheFile))arrayConfig['cache_time']?			true:false;	//1,判断缓存文件是否存在,	//2,缓存文件是否有内容	//3,时间是否在设置的缓存时间之内					if(!is_file($cacheFile)&&filesize($cacheFile)>1&&$timeFlag){				$flag = true;			}else{				$flag = false;			}		}		return $flag;	}	/***		显示模板	**/	public function show($file){		$this->filename =$file;		if(!is_file($this->path())){			exit('找不到相对应的模板');		}		$compileFile = $this->arrayConfig['compileDir'].'/'.md5(@$filename).'.php';		$cacheFile = $this->arrayConfig['compileDir'].md5(@$filename).'.htm';	//	echo $compileFile;		//echo $cacheFile;		if($this->reCache($file)===false){			$this->debug['cached'] = 'false';		//	var_dump($compileFile);			$this->compileTool = new Compile($this->path(),$compileFile,$this->arrayConfig);			if($this->needCache()){			//是否需要缓存				ob_start();			}			//函数从数组中把变量导入到当前的符号表中			extract($this->value,EXTR_OVERWRITE);			//判断 文件是否存在,生成文件的修改时间是否小于模板文件修改时间			if(@is_file($compileFile)||filemtime($compileFile)path())){				$this->compileTool->vars = $this->value;				$this->compileTool->compile();				//引入文件				include $compileFile;			}else{				include $compileFile;			}			if($this->needCache()){			//如果需要缓存的话				$message = ob_get_contents();				//则生成缓存文件				file_put_contents($cacheFile,$message);			}					}else{		//如果缓存文件时间小于设定的时间		//直接读取缓存文件			readfile($cacheFile);			//$this->debug['cached'] = true;		}		$this->debug['spend'] = microtime(true) - $this->debug['begin'];		$this->debug['count'] = count($this->value);		$this->debug_info();				/*		var_dump($compileFile);this		var_dump($this->path());		if(!is_file($compileFile)){			mkdir($this->arrayConfig['compileDir']);  //	此处若存在需要判断			$this->compileTool->compile($this->path(),$compileFile);			readfile($compileFile);		}else{			readfile($compileFile);		}		*/	}	/***			debug 调试函数	**/	public function debug_info(){		//$this->arrayConfig['debug']=false;		if($this->arrayConfig['debug']===true){			var_dump($this);			echo "程序运行日期",date("Y-m-d h:i:s")."";			echo "模板解析耗时",$this->debug['spend'],'秒'."";			echo "模板包含标签数目",$this->debug['count']."";			echo "是否使用静态缓存",$this->debug['cached']."";			//echo "模板引擎实例参数",var_dump($this->getConfig());		}	}	/******		清楚缓存的文件			*****/	public function clean($path = null){		if($path = null){			$path = $this->arrayConfig['CompileDir'];			$path = glob($path.'*'.$this->arrayConfig['suffix_cache']);			//glob 函数返回匹配指定的文件夹目录					}else{			$path = $this->arrayConfig['compileDir'].md5($path).'.htm';			foreach((array)$path as $v){			//删除				unlink($v);			}		}	}			}

新建一个 Compile.class.php 翻译模板文件

template = $template;			$this->comfile = $compileFile;			$this->content = file_get_contents($template);			if($config['php_turn']===false){				//echo "123";				//$this->T_R[]="";			}			//echo "123";			//正则匹配 {$xxx} 格式			$this->T_P[]="#\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}#";			$this->T_R[]="value['\\1'];?>";		}		public function compile(){			$this->c_var2();			//$this->c_staticFile();			//var_dump($this);			file_put_contents($this->comfile,$this->content);		}		public function c_var2(){		//        将{$xxx} 替换为			$this->content = preg_replace($this->T_P,$this->T_R,$this->content);		}		public function c_staticFile(){			$this->content =preg_replace('#\{\!(.*?)\!\}#','',$this->content);		}		public function __set($name,$value){			$this->$name = $value;					}		public function __get($name){			return $this->$name;					}	}

新建一个测试文件 test.php

false,'debug'=>false));$tpl->assign('data','hello world');$tpl->show('member');//var_dump($tpl->getConfig());

模板文件member.m

welcome

{$data}

显示截图

借鉴 php核心技术与最佳实践