|
一直在用smarty,總覺得它過于臃腫。所以自己寫了一個(gè)。 在跟目錄建index.php文件,內(nèi)容 php header ( 'Content-Typetexthtml;charset=utf-8' ); 網(wǎng)站跟目錄 define ( 'ROOT_PATH' , $_SERVER ['DOCUMENT_ROOT'].'zero' ); 存放模板文件夾 define('ZR_DIR' , ROOT_PATH.'templates'); 編譯文件夾 define('ZR_C_DIR' , ROOT_PATH.'templates_c'); require ROOT_PATH.'classzero.class.php'; $ZR = new Zero(); $ZR-assign('name','潘澤學(xué)的模板'); $ZR-assign('if',true); $array = array('1'='1','2'='2'); $ZR-assign('array',$array); $ZR-debug('index.html'); $ZR-display('index.html'); 在跟目錄建templates文件夾,再在templates文件夾內(nèi)建 index.html文件,內(nèi)容 <html> <head> <head> <body> {$name} {#}........{#} {if $if} div當(dāng)$if等于true時(shí)會(huì)顯示這句話div {if} foreach語句br {$array-foreach(key,value)} {@key}={@value}br {foreach} </body> </html> 在跟目錄建templates_c文件夾,無內(nèi)容但此文件夾要有寫權(quán)限。 在跟目錄建class文件夾。 在class文件夾內(nèi)建zero.class.php文件,內(nèi)容 php class Zero{ 保存模板變量 private $_zr_vars; 保存模板文件名 private $_zr_file; 保存ZoreParser對(duì)象(編譯對(duì)象) private $_parser; 保存ZoreDebug對(duì)象(調(diào)試對(duì)象) private $_debugger; 構(gòu)造函數(shù) public function __construct(){ 判斷模板文件夾和編譯文件夾是否存在 if(!is_dir(ZR_DIR) !is_dir(ZR_C_DIR)){ exit('錯(cuò)誤請(qǐng)正確設(shè)置模板文件夾和編譯文件夾'); } } 設(shè)置模板變量 public function assign($var,$value){ 判斷$var是否有值 if(isset($var) && trim($var) != ''){ $this-_zr_vars[$var] = $value; return true; } else { exit('錯(cuò)誤請(qǐng)?jiān)O(shè)置變量名'); } } 檢測模板是否更新,更新則再編譯,沒有更新就用原來編譯后的文件 public function display($zr_file){ $template_file = ZR_DIR.$zr_file; 判斷模板文件是否存在 if(!file_exists($template_file)){ exit('錯(cuò)誤模板文件不存在'); } $parsed_file = ZR_C_DIR.md5($zr_file).'.php'; if(!file_exists($parsed_file) filemtime($parsed_file) filemtime($template_file)){ if(TRUE){ require_once ROOT_PATH.'classzero_parser.class.php'; $this-_parser = new ZeroParser(); $this-_parser-compile($zr_file); } include $parsed_file; } public function debug($zr_file){ if(include_once(ROOT_PATH.'classzero_debugger.class.php')){ $this-_debugger = new ZeroDebuger($zr_file); $this-_debugger-start(); } else { exit('錯(cuò)誤Debuger類文件不存在'); } } } 在class文件夾內(nèi)建zero_debugger.class.php文件,內(nèi)容 php class ZeroDebuger{ private $template; 用來保存模板的內(nèi)容 private $IF_LINE_NUM; 用來保存IF所在的行數(shù) private $ENDIF_LINE_NUM; 用來保存ENDIF所在的行數(shù) private $FOREACH_LINE_NUM; 用來保存FOREACH所在的行數(shù) private $ENDFOREACH_LINE_NUM; 用來保存ENDFOREACH所在的行數(shù) private $ERRORS; 用來保存錯(cuò)誤信息 構(gòu)造函數(shù) public function __construct($file_name = NULL){ if(isset($file_name) && trim($file_name) != ''){ $this-set_file($file_name); } } 打開模板文件并讀取文件內(nèi)容 public function set_file($file_name){ $file_name = ZR_DIR.$file_name; if(file_exists($file_name)){ $fp = fopen($file_name,'r') OR exit('錯(cuò)誤不能打開模板文件 '); if(($fs = filesize($file_name)) 0) $this-template = fread($fp,$fs); fclose($fp); return true; } exit('錯(cuò)誤模板文件不存在'); } function start($display = FALSE){ 判斷是否有{#} (注釋) if(strpos($this-template,'{#}') != false){ 判斷是否有{#}......{#} if(!preg_match({#}[^({#})]{#} , $this-template)){ $this-ERRORS[] = '錯(cuò)誤{#}沒有關(guān)閉'; } } 把模板內(nèi)容按換行來分割成數(shù)組 $this-template = explode(n , $this-template); 循行數(shù)組 $line_number =1; foreach($this-template as $line){ 匹配{if....語句,并保存行數(shù)到IF_LINE_NUM變量中 if(preg_match({sif , $line)){ $this-IF_LINE_NUM[] = $line_number; } 匹配{if}語句,并保存行數(shù)到ENDIF_LINE_NUM if(preg_match({sifs} , $line)){ $this-ENDIF_LINE_NUM[] = $line_number; } 匹配{$array_name-foreach(key, value)....語句,并保存行數(shù) 到FOREACH_LINF_NUM變量中 if(preg_match({s$[0-9a-zA-Z_]+-foreach(s[0-9a-zA-Z_]+s,s[0- 9a-zA-Z_]+s)s , $line)){ $this-FOREACH_LINE_NUM[] = $line_number; } 匹配{foreach}語句,并保存行數(shù)到ENDFOREACH變量中 if(preg_Match({sforeachs} , $line)){ $this-ENDFOREACH_LINE_NUM[] = $line_number; } 檢測include語法是否正確(是否符合{include .......}) if(strpos($line , {include) != false){ if(!preg_match({include [^}]} , $line)){ $this-ERRORS[] = '錯(cuò)誤INCLUDE語法使用錯(cuò)誤,在行font color=red'.$line_number.'font'; } } $line_number++; } 調(diào)用if和foreach兩個(gè)方法 $this-check_if(); $this-check_foreach(); if(count($this-ERRORS) 0){ echo 'div style=border1px solid #f60;padding10px;width500px;font-size12px;color#800;'; foreach($this-ERRORS as $e){ echo $e,'br'; } echo 'div'; } else { if($display) echo $this-highlight_html(implode('',$this-template)); echo 'div style=border1px solid #f60;padding10px;width200px;font-size12px;test-aligncenter; color#800;恭喜模板沒有錯(cuò)誤div'; } } 檢測{if .......}.....{if}語句是否合理或是否關(guān)閉 private function check_if(){ $ifs = count($this-IF_LINE_NUM); for($i = 0; $i $ifs; $i++){ if(isset($this-ENDIF_LINE_NUM[$i])){ if($this-IF_LINE_NUM[$i] $this-ENDIF_LINE_NUM[$i]){ $this-ERRORS[] = '錯(cuò)誤在沒有IF的情況下使用END IF,在行 font color=red'.$this-IF_LINE_NUM[$i].'font'; } } else { $this-ERRORS[] = '錯(cuò)誤IF沒有關(guān)閉,在行font color=red'.$this-IF_LINE_NUM[$i].'font'; } if(count($this-IF_LINE_NUM) == 0 && count($this-ENDIF_LINE_NUM) 0){ foreach($this-ENDIF_LINE_NUM as $line_number){ $this-ERRORRS[] = '錯(cuò)誤在沒有IF的情況下使用END IF,在 行font color=red'.$line_number.'font'; } } } print_r($this-FOREACH_LINE_NUM); } 檢測{$array_name-foreach(key, value)}....................{foreach}語句是否合理或是否關(guān)閉 private function check_foreach(){ $foreachs = count($this-FOREACH_LINE_NUM); for($i = 0 ; $i $foreachs ; $i++){ if(isset($this-ENDFOREACH_LINE_NUM[$i])){ if($this-FOREACH_LINE_NUM[$i] $this-ENDFOREACH_LINE_NUM[$i]){ $this-ERRORS[] = '錯(cuò)誤在沒有FOREACH的情況下使用END FOREACH,在行font color=red'.$this-ENDFOREACH_LINE_NUM[$i].'font'; } } else { $this-ERRORS[] = '錯(cuò)誤FOREACH沒有關(guān)閉,在行font color=red'.$this-FOREACH_LINE_NUM[$i].'font'; } } if(count($this-FOREACH_LINE_NUM) == 0 && count($this-ENDFOREACH_LINE_NUM) 0){ foreach($this-ENDFOREACH_LINE_NUM as $line_number){ $this-ERRORS[] = '錯(cuò)誤在沒有FOREACH的情況下使用END FOREACH,在行font color=red'.$line_number.'font'; } } } private function highlight_html($code){ $code = str_replace('','',$code); $code = str_replace('','',$code); $code = preg_replace('([a-zA-Z_]+)=','font color=#FF0000$1=font',$code); $code = preg_replace('([a-zA-Z0-9$;]+)','font color=#0000FF$1font',$code); $code = str_replace('!--','font color=#008080!--',$code); $code = str_replace('--','--font',$code); $code = n12br($code); return $code; } } 在class文件夾內(nèi)建zero_parser.class.php文件,內(nèi)容 php class ZeroParser{ 用來保存模板內(nèi)容 private $template; 設(shè)置和讀取模板 private function set_file($file){ 模板路徑 $file = ZR_DIR.$file; if(!file_exists($file)){ exit('錯(cuò)誤模板文件不存在'); } 打開模板文件 $fp = fopen($file,'r'); if(!$fp) exit('錯(cuò)誤不能打開文件'); if(filesize($file)){ 讀取模板文件的內(nèi)容 $this-template = fread($fp,filesize($file)); } else { exit('錯(cuò)誤模板文件大小為零'); } 關(guān)閉打開的文件 fclose($fp); return true; } 解析變量 private function _parse_var(){ 變量匹配正則 $patten = '{$([a-zA-Z0-9]+)}'; if(strpos($this-template,'{$') !== false){ 正則替換 $this-template = preg_replace($patten,php echo $this-_zr_vars['$1']; ,$this-template); } return true; } 解析IF條件語句 private function _parse_if(){ 判斷模板文件中是否有IF語句 if(preg_match({sif,$this-template)){ if(preg_match('{sifs}',$this-template)){ $if_patten = {sifs+$([a-zA-Z0-9]+)}; $ef_patten = {sifs}; $this-template = preg_replace($if_patten,php if($this-_zr_vars['$1']){,$this-template); $this-template = preg_replace($ef_patten,php }; ,$this-template); } else { exit('錯(cuò)誤語法錯(cuò)誤,沒有封閉IF條件語句'); } } return true; } 解析注釋語句 private function _parse_common(){ $patten = {#}([^{]){#}; if(strpos($this-template,'{#}') !== false){ $this-template = preg_replace($patten,php $1 ,$this-template); } return true; } include語句 private function _parse_include(){ if(preg_match({sinclude ([^}])s},$this-template,$file)){ if(trim($file[1]) == '') exit('錯(cuò)誤文件指定包含的文件'); if(!file_exists(trim($file[1]))) exit('錯(cuò)誤文件不存在'); $include_patten = '{sinclude ([^]+)S}'; $include_patten = preg_replace($include_patten,php include '$1'; ,$this-template); } return true; } 解析Foreach語句 private function _parse_foreach(){echo 'aa'; if(preg_match({s$[0-9a-zA-Z_]+-foreach(s[0-9a-zA-Z_]+s,s[0-9a-zA-Z_]+s)s , $this-template)){ echo 'dd'; if(preg_match({sforeachs},$this-template)){ 循環(huán)內(nèi)的變量 如{@key} if(preg_match({s@[0-9a-zA-Z_],$this-template)){ $k_and_v_patten = {s@([0-9a-zA-Z_]+)s}; $this-template = preg_replace($k_and_v_patten,php echo $$1; , $this-template); } $foreach_patten = {s$([0-9a-zA-Z_]+)s-sforeach(s([0-9a-zA-Z_]+)s,s([0-9a-zA-Z_]+)s)s}; $end_foreach_patten = {sforeachs}; $this-template = preg_replace($foreach_patten,php foreach($this-_zr_vars['$1'] as $$2 = $$3){ ,$this-template); $this-template = preg_replace($end_foreach_patten,php }; ,$this-template); } else { exit('錯(cuò)誤語法錯(cuò)誤,沒有封閉FOREACH條件語句'); } } } compile方法 public function compile($file_name){ $this-set_file($file_name); 讀取模板文件 $this-_parse_var(); $this-_parse_if(); 解析if語句 $this-_parse_common(); 解析注釋語句 $this-_parse_foreach(); 解析foreach()語句 $this-_parse_include(); 解析include()語句 $zr_c_file = ZR_C_DIR.md5(basename($file_name)).'.php'; 產(chǎn) 生縞譯后的文件名 $fp = fopen($zr_c_file,'w'); fwrite($fp,$this-template); fclose($fp); } } 在是和smarty一樣要編譯后才可運(yùn)行的模板引擎,下面在說個(gè)不用編譯的,這總方法就有點(diǎn)像cake自帶的模板引擎。不說這什么多了,先看看代碼吧。 建個(gè)index.php文件,內(nèi)容 php 檢查zero類是否已定義 if(!class_exists('zero')){ require 'zero.php'; } class controller{ private $zero = NULL; public function __construct(){ $this-zero = new zero(); 告訴模板引擎加載哪個(gè)模板 $this-zero-load('index.html'); } public function index(){ $parameter = '我是由模板引擎?zhèn)鬟^來的!'; $this-zero-set('parameter',$parameter); $this-zero-set('arr',array(1,2,3,4,5,6,7)); } } $cont = new controller(); $cont-index(); 建個(gè)zero.php文件,內(nèi)容 php 模板引擎 class zero{ 模板 private $templet = NULL; 變量數(shù)組 private $variable = array(); public function __construct(){ } public function load($path){ $this-templet = $path; } public function set($key,$value){ $this-variable = array_merge($this-variable,array( $key=$value )); } function __destruct(){ extract($this-variable,EXTR_PREFIX_SAME,'zero'); require dirname ( __FILE__ ).'Temp'.$this-templet; } } 這就完事了,要是有什么不會(huì)的可以給我留言。
信息發(fā)布:廣州名易軟件有限公司 http://www.jetlc.com
|