PHP模板二(仿DEDE)

今天看了下正則表達式,忽然覺得可以把我現在手上的企業建站系統改一下。不過改來改去覺得還是仿DEDE的方式好一點。

於是開始看DEDE是如何處理標籤的。於是經過一上午的學習,我發現了一個正則表達式

/({t:*[^{]*\/}|{t:*[^}]*}([^{]|(?R))*{\/t:.*?})/i
但是對我於這個系統來說,那就簡單得多,所以參照這個我做了以下的正則表達式

 

private $preg_string = "/(<m:*[^<]*>|<\/m:*[^<]*>)/si";


 

//tag數組
$tag_arr = array();
//文件內容
$file_content = file_get_contents($file);
//正則解析
preg_match_all($this->preg_string , $file_content , $m);
foreach($m[0] as $key => $value){
	//標籤字符串
	$tag_arr[$key]['str'] = $value;
	$vs = explode(':' , $value);
	//標籤名
	$va = explode(' ' , $vs[1]);
	if(strpos($value , '/')==1){
		$tag_arr[$key]['tag_name'] = 'end';
	}
	else{
		$tag_arr[$key]['tag_name'] = $va[0];
	}
	
	unset($va[0]);
	foreach($va as $name => $item){
		$val = strtr($item , array('"'=>'' , '\''=>'' , '>'=>'' , '/>'=>''));
		$val_arr = explode('=' , $val);
		$property[$val_arr[0]] = $val_arr[1];
	}
	//標籤屬性數組
	$tag_arr[$key]['property'] = $property;
	unset($property);
}
var_dump($tag_arr);

$tag_arr數組的格式如下


然後用PHP的str_replace方式替換$tag_arr['str']

以下是源碼

stemplate.class.php

<?php
class stemplate{
	//源文件目錄
	public $template_dir = './template/';
	//緩存目錄 
	public $cache_dir = './cache/';
	//編譯目錄
	public $template_c_dir = './template_c/';
	//編譯文件
	private $template_c_file = '';
	//緩存文件
	private $cache_file = '';
	//源文件
	public $template_file = '';
	//核心正則
	private $preg_string = "/(<m:*[^<]*>|<\/m:*[^<]*>)/si";
	/**
	 *顯示頁面
	 *@param $file String 文件名
	 */
	public function display($file){
		echo $this->fetch($file);
	}
	
	/**
	 *將頁面寫入緩衝區然後輸入
	 *@param $file String 文件名
	 */
	public function fetch($file){
		//替換內容
		$content = '';
		//模板文件全路徑
		$template_file = $this->template_dir . $file;
		//模板文件名
		$this->template_file = $file;
		if(file_exists($template_file)){
			//分析
			$content = $this->token($template_file);
		}
		else{
			exit($template_file . '--模板文件不存在');
		}
		//將文件緩存
		$this->store_file($content , 'complie');
		//導入到當前
		include $this->template_c_dir . $this->template_c_file;
	}
	
	/**
	 *分析內容
	 *@return $complie_content String 編譯內容
	 *@param $file String 文件名
	 */
	private function token($file){
		//tag數組
		$tag_arr = array();
		//文件內容
		$file_content = file_get_contents($file);
		//正則解析
		preg_match_all($this->preg_string , $file_content , $m);
		foreach($m[0] as $key => $value){
			//標籤字符串
			$tag_arr[$key]['str'] = $value;
			$vs = explode(':' , $value);
			//標籤名
			$va = explode(' ' , $vs[1]);
			if(strpos($value , '/')==1){
				$tag_arr[$key]['tag_name'] = 'end';
			}
			else{
				$tag_arr[$key]['tag_name'] = $va[0];
			}
			
			unset($va[0]);
			foreach($va as $name => $item){
				$val = strtr($item , array('"'=>'' , '\''=>'' , '>'=>'' , '/>'=>''));
				$val_arr = explode('=' , $val);
				$property[$val_arr[0]] = $val_arr[1];
			}
			//標籤屬性數組
			$tag_arr[$key]['property'] = $property;
			unset($property);
		}
		var_dump($tag_arr);
		$complie_content = $this->token_array($tag_arr , $file_content);
		
		return $complie_content;
	}
	
	/**
	 *返回替換標籤後的內容
	 *@return $complie_content String 編譯內容
	 *@param $src_array String 屬性數組
	 *@param $content String 文件內容
	 */
	private function token_array($src_array , $content){
		$file_desc_content = $content;
		foreach($src_array as $value){
			if($value['tag_name'] == 'end'){
				$file_desc_content = str_replace($value['str'] , '<?php } ?>' , $file_desc_content);
			}
			else{
				//導入標籤類
				require_once './m.class.php';
				$m_class    = new m();
				$m_function = '_' . $value['tag_name'];
				if(method_exists($m_class, $m_function)){
					$tag_string = '';
					if($value['tag_name'] == 'include'){
						$tag_string = $m_class->$m_function($value['property']['file'] , $this->template_dir);
					}
					else{
						$tag_string = $m_class->$m_function($value['property']);
					}
					$file_desc_content = str_replace($value['str'] , $tag_string , $file_desc_content);
					unset($tag_string);
				}
			}
		}
		return $file_desc_content;
	}
	
	/**
	 *儲存文件到編譯,緩存
	 *@param $content string 內容
	 *@param $store_type string 方式
	 */
	public function store_file($content , $store_type = 'cache'){
		$desc_file = '';
		if($store_type == 'cache'){
			$this->cache_file = md5($this->template_file) . $this->template_file . '.html';
			$desc_file        = $this->cache_dir . $this->cache_file;
		}
		else{
			$this->template_c_file = md5($this->template_file) . $this->template_file . '.php';
			$desc_file             = $this->template_c_dir . $this->template_c_file;
		}
		$fp = fopen($desc_file , 'w') or die('can not open file');
		fputs($fp,$content);
		fclose($fp);
		unset($fp);
	}
}
?>

index.php

<?php

require './stemplate.class.php';

$template = new stemplate();

$template->display('index.htm');

index.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>模板</title>
</head>

<body>
<b>正常輸出</b><br/>
<?php echo '正常的PHP輸出'; ?><br/>
<b>foreach循環</b><br/>
<?php $temp_arr = array('aa' , 'bbb'); ?>
<m:foreach from='$temp_arr' value='cc'>
	<td><m:field name='cc' /></td>
</m:foreach>
</body>
</html>

m.class.php

<?php
class m{
	public function _foreach($property=null){
		$from = $property['from'];
		$value = $property['value'];
		$content = "<?php foreach($from as \$$value){ ?>";
		return $content;
	}
	
	public function _field($property=null){
		return "<?php echo \${$property['name']}; ?>";
	}
}


發佈了48 篇原創文章 · 獲贊 16 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章