今天看了下正则表达式,忽然觉得可以把我现在手上的企业建站系统改一下。不过改来改去觉得还是仿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); } } ?>
<?php require './stemplate.class.php'; $template = new stemplate(); $template->display('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>
<?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']}; ?>"; } }