今天看了下正則表達式,忽然覺得可以把我現在手上的企業建站系統改一下。不過改來改去覺得還是仿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']}; ?>";
}
}