知识屋:更实用的电脑技术知识网站
所在位置:首页 > 编程技术 > PHP编程

一个编译型的PHP模板引擎大致实现过程

发布时间:2015-05-27 19:33:41作者:知识屋

JTemplate.class.php

001
<?php
002
/**
003
 * <a href="http://my.oschina.net/arthor" target="_blank" rel="nofollow">@author</a>  Jiawei
004
 * @Completed in 2012-6-29 0:23
005
 */
006
class JTemplate{
007
    //通过assign函数传入的变量临时存放数组
008
    private $templateVar = array();
009
    //模板目录
010
    private $templateDir = '';
011
    //编译目录
012
    private $templateCompileDir = '';
013
    
014
    private $fileName = '';
015
    /**
016
     * 构造函数
017
     * @param string $templateDir 模板目录
018
     * @param string $templateComplieDir 模板编译目录
019
     */
020
    public function __construct($templateDir,$templateComplieDir){
021
        $this->templateDir = $templateDir;
022
        $this->templateCompileDir = $templateComplieDir;
023
    }
024
    /**
025
     * 显示模板
026
     * @param string $fileName 模板文件名
027
     */
028
    public function display($fileName){
029
        $this->fileName = $fileName;
030
        if(file_exists($this->templateDir.'/'.$this->fileName)){
031
            $compileFileName = $this->templateCompileDir.'/'.$this->file_safe_name().'.php';
032
            if(!file_exists($compileFileName) || filemtime($compileFileName)< filemtime($this->templateDir.'/'.$this->fileName)){
033
                $this->del_old_file();
034
                $this->compile();
035
            }
036
            extract($this->templateVar);
037
            include $compileFileName;
038
        }else{
039
            $this->error('Sorry,the template file '.$this->fileName.' does not exist!!');
040
        }
041
    }
042
    /**
043
     * 获取编译文件名
044
     */
045
    private function get_compile_file(){
046
        $compileFile = explode('.',$this->fileName);
047
        unset($compileFile[count($compileFile)-1]);
048
        return implode('.',$compileFile);
049
    }
050
    /**
051
     * 编译
052
     */
053
    private function compile(){
054
        $fileHandle = @fopen($this->templateDir.'/'.$this->fileName, 'r');
055
        while(!feof($fileHandle)){
056
            $fileContent = fread($fileHandle,1024);
057
        }
058
        fclose($fileHandle);
059
        $fileContent = $this->template_replace($fileContent);
060
        //$compileFile = $this->get_compile_file($fileName);
061
        $fileHandle = @fopen($this->templateCompileDir.'/'.$this->file_safe_name().'.php','w');
062
        if($fileHandle){
063
            fwrite($fileHandle, $fileContent);
064
            fclose($fileHandle);
065
        }else{
066
            $this->error('Sorry,Compile dir can not write!');
067
        }
068
    }
069
    /**
070
     * 模板传值
071
     * @param string $valueName 模板中使用的变量名
072
     * @param $value 变量值
073
     */
074
    public function assign($valueName,$value){
075
        $this->templateVar[$valueName] = $value;
076
    }
077
    
078
    /**
079
     * 模板正则替换
080
     * @param string $content 替换内容
081
     * <a href="http://my.oschina.net/u/556800" target="_blank" rel="nofollow">@return</a>  string 替换过后的内容
082
     */
083
    private function template_replace($content){
084
        $orginArray = array(
085
            '/<!--loop/s+/$(/w+)/s+/$(/w+)-->/s',
086
            '/<!--loop/s+/$(/w+)/s+/$(/w+)/s+/$(/w+)-->/s',
087
            '/<!--elseloop-->(.+?)<!--endloop-->/s',
088
            '/<!--endloop-->/s',
089
            '/<!--if/s+/((.+?)/)-->/s',
090
            '/<!--endif-->/s',
091
            '/<!--elseif/s+/((.+?)/)-->/s',
092
            '/<!--else-->/s',
093
            '//{P:(.+?)/:}/s',
094
            '//{C:(/w+)/}/s',
095
            '//{I:(.+?)/}/s',
096
            '//{F:(.+?)/}/s',
097
            '//{EF:(.+?)/}/s',
098
            '//{([a-zA-Z0-9_/[/]/'/"/$/./x7f-/xff]+)/}/s',
099
        );
100
        
101
        $changeArray = array(
102
            '<?php if(!empty($$1)&&is_array($$1)){$countLoop = 1;foreach($$1 as $$2){$countLoop++;?>',
103
            '<?php if(!empty($$1)&&is_array($$1)){$countLoop = 1;foreach($$1 as $$2=>$$3){$countLoop++;?>',
104
            '<?php }if(!empty($countLoop))$countLoop--;}else{?>$1<?php }?>',
105
            '<?php }if(!empty($countLoop))$countLoop--;}?>',
106
            '<?php if($1){?>',
107
            '<?php }?>',
108
            '<?php }elseif($1){?>',
109
            '<?php }else{?>',
110
            '<?php $1?>',
111
            '<?php echo $1;?>',
112
            '<?php include_once "'.$this->templateDir.'/$1";?>',
113
            '<?php $1;?>',
114
            '<?php echo $1;?>',
115
            '<?php echo $$1;?>',
116
        );
117
        return $repContent=preg_replace($orginArray,$changeArray,$content);
118
    }
119
    /**
120
     * 删除旧文件
121
     */
122
    private function del_old_file(){
123
        $compileFile = $this->get_compile_file($this->fileName);
124
        $files = glob($this->templateCompileDir.'/'.$compileFile.'*.php');
125
        // print_r($files);
126
        if($files){
127
            @unlink($files[0]);
128
        }
129
    }
130
    /**
131
     * 编译文件名安全处理方法
132
     * <a href="http://my.oschina.net/u/556800" target="_blank" rel="nofollow">@return</a>  string 返回编译文件名
133
     */
134
    private function file_safe_name(){
135
        $compileFile = $this->get_compile_file($this->fileName);
136
        return $compileFile.filemtime($this->templateDir.'/'.$this->fileName);
137
    }
138
    
139
    /**
140
     * 错误输出函数
141
     * @param string $content 错误输出信息
142
     */
143
    private function error($content){
144
        $stringHtml = '<div style="width:780px;height:auto;padding:10px;border:1px solid #CCC;margin:0 auto;">';
145
        $stringHtml .= 'Error information:<br />';
146
        $stringHtml .= '<font color="red">';
147
        $stringHtml .= $content;
148
        $stringHtml .= '</font>';
149
        $stringHtml .= '</div>';
150
        exit($stringHtml);
151
    }
152
}
153
?>
index.php

view sourceprint?
01
<?php
02
/**
03
 * @author Jiawei
04
 */
05
include_once 'JTemplate/JTemplate.class.php';
06
$template = new JTemplate('template','compile');
07
$a = array('a','b','c','d');
08
define('_CORE_','aaa');
09
$template->assign('a', $a);
10
$template->display('index.html');
11
?>
 作者:袁家伟

(免责声明:文章内容如涉及作品内容、版权和其它问题,请及时与我们联系,我们将在第一时间删除内容,文章内容仅供参考)
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜