自己写一个简单的模版引擎

   现在离职在家,突然发现没什么事儿做了,就研究研究了smarty,写了一个简单的搜索引擎。包含

assign赋值,display模版解析的方法,

新建一个MyTpl.class.php(其他名称也可以)

   代码如下:

<?php
class MyTpl{
    //初始化函数
    function __construct($template_dir='templates/',$compile_dir='templates_c'){
        $this->template_dir=rtrim($template_dir,'/').'/';
        $this->compile_dir=rtrim($compile_dir,'/').'/';
        $this->tpl_vars=array();
    }
                                                                                    
    //赋值函数
    function assign($tpl_var,$value=null){
        if ($tpl_var!='')   $this->tpl_vars[$tpl_var]=$value;
    }
                                                                                    
    //模版解析
    function display($fileName){
        $tplFile=$this->template_dir.$fileName;
        if (!file_exists($tplFile))     return false;
                                                                                        
        $comFileName=$this->compile_dir.'com_'.basename($tplFile).'.php';
                                                                                        
        if (!file_exists($comFileName)||filemtime($comFileName)<filemtime($tplFile)){
            $repContent=$this->tpl_replace(file_get_contents($tplFile));
            $handle=fopen($comFileName, 'w+');
            fwrite($handle, $repContent);
            fclose($handle);
        }
        require_once $comFileName;
    }
                                                                                    
    //模版替换函数
    private function tpl_replace($content){
        $pattern=array(
                '/<\{\s*\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-xff]*)\s*\}>/i',     //解析变量
                '/<\{\s*if\s*(.+?)\s*\}>(.+?)<\{\s*\/if\s*\}>/ies',                         //if标签解析
                '/<\{\s*else\s*if\s*(.+?)\s*\}>/',                                                                //elseif解析
                '/<\{\s*else\s*\}>/',                                                                                 //else解析
                '/<\{\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*\}>(.+?)<\{\\s*\/loop\s*}>/is',     //匹配loop标签
                '/<\{\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*=>\s*\$(\S+)\s*\}>(.+?)<\{\s*\/loop\s*\}>/is>/',//遍历loop中的键和值
                '/<\{\s*include\s+[\"\']?(.+?)[\"\']?\s*\}>/ie',                          //匹配include
        );
        //替换成php
        $replacement=array(
                '<?php echo $this->tpl_vars["${1}"]?>',                //变量替换
                '$this->stripvtags(\'<?php if(${1}){?>\',\'${2}<?php}?>\')',
                '$this->stripvtags(\'<?php } elseif(${1}) { ?>\',"")',
                '<?php } else { ?>',
                '<?php foreach($this->tpl_vars["${1}"] as $this->tpl_vars["${2}"]) { ?>${3}<?php } ?>',
                '<?php foreach($this->tpl_vars["${1}"] as $this->tpl_vars["${2}"]=>$this->tpl_vars["${3}"]){?>$(4)<?php } ?>',
                'file_get_contents($this->template_dir."${1}")'
        );
                                                                                        
        $repContent=preg_replace($pattern, $replacement, $content);
        if (preg_match('/<\{([^(\}>)]{1,})\}>/', $repContent)){
            $repContent=$this->tpl_replace($repContent);
        }
        return $repContent;
    }
    //替换条件语句中对应的值
    private function stripvtags($expr,$statement){
        $var_pattern='/\s*\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*/is';
        $expr=preg_replace($var_pattern, '$this->tpl_vars["${1}"]', $expr);
        $expr=str_replace("\\\"", "\"", $expr);
        $statement=str_replace("\\\"", "\"", $statement);
        return $expr.$statement;
    }
}


   以上很简单,就是赋值,然后做模版解析以后再输出,最复杂的一部分就是正则替换这一部分,写了很久,有时间还是借鉴一下smarty的吧。

   接下来就测试一下,新建一个inde.php

require_once 'plugins/MyTpl.class.php';
$Tpl=new MyTpl();
$title='第一个标题';
$Tpl->assign('title',$title);
$Tpl->display('index.tpl');

并且新建templates目录,templates_c目录其他根据实际情况来写,然后在templates中新建一个index.tpl,写上相应的代码,我只是做一个简单的测试,

<html>
    <head><title><{$title}></title></head>
    <body>
    <{$title}>
    </body>
</html>

然后在浏览器中预览,就可以实现,我写的正则替换里,也包括一个loop的foreach替换标签。大家可以继续扩展完善,我也会继续完善一套自己的模版引擎。


footer.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值