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