默默简单的写了一个模板引擎


Posted in PHP onJanuary 02, 2007

引擎文件 

<?php  
/**  
* 默默基于Discuz的模板引擎开发的OOP类模板引擎,可支持模板缓存并生成hash的md5值。由hash值来判断模板是否被修改,假如被修改则重新生成缓存文件,假如没有被修改,则直接调用缓存文件.  
* 版本:1.0.0.1 beta 测试版  
*/  
class mmtp{          var $left_tags="{";  
        var $right_tags="}";  
        var $tp_suffix=".html";  
        var $cache_suffix=".tpl";  
        var $tp_dir="./";  
        var $cache_dir="./";  
        /**  
         * 允许循环嵌套的次数,默认为5  
         *  
         * @var unknown_type  
         */  
        var $nest = 5;      
    /**  
     * 模板路径  
     *  
     * @param unknown_type $tp_dir  
     * @return mmtp  
     */  
        function __setdir($tp_dir){  
                        if(file_exists($tp_dir)){  
                                $this->tp_dir=$tp_dir;  
                        }else{  
                                $this->error("模板路径不存在");  
                        }  
        }  
        /**  
         * 设置缓存目录  
         *  
         * @param unknown_type $cache_dir  
         */  
        function __setcdir($cache_dir){  
                                if(file_exists($cache_dir)){  
                                $this->cache_dir=$cache_dir;  
                        }else{  
                                $this->error("缓存路径不存在");  
                        }  
        }  
    /**  
     * 输出错误信息  
     *  
     * @param unknown_type $msg  
     */  
        function error($msg){  
                print "<div style=\"font-size:12px;color:red;\">".$msg."</div>";  
        }  
        /**  
         * 解析模板  
         *  
         * @param unknown_type $file  
         */  
        function tp($file){  
                $tp_path=$this->tp_dir.$file.$this->tp_suffix;  
                $fp=fopen($tp_path,"rb");  
                if(!$this->file_test($tp_path,"r") && !$this->match_hash($file)){  
                        $template=$this->file_read($tp_path);  
                    $var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";  
                    $const_regexp = "([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)";  
                        $template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);  
                        $template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);  
                        $template = preg_replace("/\{lang\s+(.+?)\}/ies", "languagevar('\\1')", $template);  
                        $template = str_replace("{LF}", "<?=\"\\n\"?>", $template);  
                        $template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $template);  
                        $template = preg_replace("/$var_regexp/es", "\$this->addquote('<?=\\1?>')", $template);  
                        $template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es", "\$this->addquote('<?=\\1?>')", $template);  
                          
                        $template = preg_replace("/[\n\r\t]*\{template\s+([a-z0-9_]+)\}[\n\r\t]*/is", "\n<? include('".$this->cache_dir."\\1".$this->cache_suffix."'); ?>\n", $template);  
                        $template = preg_replace("/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/is", "\n<? include('".$this->cache_dir."\\1".$$this->cache_suffix."'); ?>\n", $template);  
                        $template = preg_replace("/[\n\r\t]*\{eval\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('\n<? \\1 ?>\n','')", $template);  
                        $template = preg_replace("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('\n<? echo \\1; ?>\n','')", $template);  
                        $template = preg_replace("/[\n\r\t]*\{elseif\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('\n<? } elseif(\\1) { ?>\n','')", $template);  
                        $template = preg_replace("/[\n\r\t]*\{else\}[\n\r\t]*/is", "\n<? } else { ?>\n", $template);  
                        for($i = 0; $i < $this->nest; $i++) {  
                        $template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r]*(.+?)[\n\r]*\{\/loop\}[\n\r\t]*/ies", "\$this->stripvtags('\n<? if(is_array(\\1)) { foreach(\\1 as \\2) { ?>','\n\\3\n<? } } ?>\n')", $template);  
                        $template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*(.+?)[\n\r\t]*\{\/loop\}[\n\r\t]*/ies", "\$this->stripvtags('\n<? if(is_array(\\1)) { foreach(\\1 as \\2 => \\3) { ?>','\n\\4\n<? } } ?>\n')", $template);  
                        $template = preg_replace("/[\n\r\t]*\{if\s+(.+?)\}[\n\r]*(.+?)[\n\r]*\{\/if\}[\n\r\t]*/ies", "\$this->stripvtags('\n<? if(\\1) { ?>','\n\\2\n<? } ?>\n')", $template);  
                        }  
                        $template = preg_replace("/\{$const_regexp\}/s", "<?=\\1?>", $template);  
                        $template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template);  
                        $hash=$this->file_hash($tp_path);  
                        $head_hash="<!-- hash=".$hash." -->";  
                        $foot_time="<!-- time=".(date("Y-m-d G:i:s"))." -->";  
                        $this->file_write($this->cache_dir.$file.".tpl",$head_hash.$template.$foot_time);  
                          
                }  
        }  
          
        /**  
         * 检查文件是否存在并且有读取权限  
         *  
         * @param unknown_type $path  
         */  
        function file_test($path,$method){  
                if(!file_exists($path) || !fopen($path,$method)){  
                        $this->error("模板文件不存在,或没有操作权限");  
                        return false;  
                }  
        }  
        /**  
         * 读取文件内容  
         *  
         * @param unknown_type $path  
         * @return unknown  
         */  
        function file_read($path,$length=0){  
                if(!$this->file_test($path,"r+")){  
                $fp=@fopen($path,"r+");  
                if($length==0){  
                        $contents=@fread($fp,filesize($path));  
                }else{  
                        $contents=@fread($fp,$length);  
                }  
                fclose($fp);  
                return $contents;  
                }  
        }  
          
        /**  
         * 写入文件内容  
         *  
         * @param unknown_type $path  
         * @param unknown_type $puts  
         */  
        function file_write($path,$puts){  
                if(!$this->file_test($path,"w+")){  
                $fp=@fopen($path,"w+");  
                @fwrite($fp,$puts);  
                fclose($fp);  
                }  
        }  
          
        /**  
         * 计算文件的hash  
         *  
         * @param unknown_type $path  
         * @return unknown  
         */  
        function file_hash($path){  
                return md5_file($path);  
        }  
          
        /**  
         * 对比模板文件与缓存文件的hash值  
         *  
         * @param unknown_type $file  
         * @return unknown  
         */  
        function match_hash($file){  
                $read_hash=$this->file_read($this->cache_dir.$file.$this->cache_suffix,46);  
                $html_hash=$this->file_hash($this->tp_dir.$file.$this->tp_suffix);  
                        if(preg_match("/".$html_hash."/i",$read_hash)){  
                        return true;  
                }  
        }  
        function addquote($var) {  
        return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));  
        }  
        function transamp($str) {  
        $str = str_replace('&', '&', $str);  
        $str = str_replace('&amp;', '&', $str);  
        $str = str_replace('\"', '"', $str);  
        return $str;  
}  
        function stripvtags($expr, $statement) {  
        $expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));  
        $statement = str_replace("\\\"", "\"", $statement);  
        return $expr.$statement;  
}  
}  

$tp=new mmtp();  
$tp->__setdir("./");  
$tp->__setcdir("./cache/");  
$tp->tp("index1");  
$_GET[it]=sdhkadajksdhajdhkajsdhjkasdjkasdhasjdhkjsadhk;  
$name=2;  
$head="欢迎使用MoMo模板引擎";  
include("./cache/index1.tpl");  
?> 

模板index.html 

{$head}
 
模板index1.html
{template index}  
{if $name==1}  
你好  
{else}  
谢谢  
{/if}  

这个模板是默默今天下午写的,写的比较仓促,也许存在漏洞,这个版本只是测试版,以后我会逐渐的去完善,先发出来,当作一个前瞻.

PHP 相关文章推荐
建立文件交换功能的脚本(二)
Oct 09 PHP
一个简单实现多条件查询的例子
Oct 09 PHP
纯php打造的tab选项卡效果代码(不用js)
Dec 29 PHP
PHP实现单例模式最安全的做法
Jun 13 PHP
kohana框架上传文件验证规则写法示例
Jul 14 PHP
浅谈本地WAMP环境的搭建
May 13 PHP
谈谈PHP中substr和substring的正确用法及相关参数的介绍
Dec 16 PHP
YII Framework教程之异常处理详解
Mar 14 PHP
centos+php+coreseek+sphinx+mysql之一coreseek安装篇
Oct 25 PHP
PHP 无限级分类
May 04 PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
Oct 19 PHP
PHP封装cURL工具类与应用示例
Jul 01 PHP
超强分页类2.0发布,支持自定义风格,默认4种显示模式
Jan 02 #PHP
PHP小技巧搜集,每个PHPer都来露一手
Jan 02 #PHP
实例(Smarty+FCKeditor新闻系统)
Jan 02 #PHP
PHP+JS无限级可伸缩菜单详解(简单易懂)
Jan 02 #PHP
PHP文件上传实例详解!!!
Jan 02 #PHP
AJAX for PHP简单表数据查询实例
Jan 02 #PHP
[原创]PHP中通过ADODB库实现调用Access数据库之修正版本
Dec 31 #PHP
You might like
php MySQL与分页效率
2008/06/04 PHP
php学习之简单计算器实现代码
2011/06/09 PHP
基于MySQL分区性能的详细介绍
2013/05/02 PHP
PHP has encountered a Stack overflow问题解决方法
2014/11/03 PHP
php天翼开放平台短信发送接口实现方法
2014/12/22 PHP
Windows下编译PHP5.4和xdebug全记录
2015/04/03 PHP
PHP Try-catch 语句使用技巧
2016/02/28 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
js form 验证函数 当前比较流行的错误提示
2009/06/23 Javascript
window.ActiveXObject使用说明
2010/11/08 Javascript
在JQuery dialog里的服务器控件 事件失效问题
2010/12/08 Javascript
js中的时间转换—毫秒转换成日期时间的示例代码
2014/01/26 Javascript
js老生常谈之this,constructor ,prototype全面解析
2016/04/05 Javascript
javascript时间戳和日期字符串相互转换代码(超简单)
2016/06/22 Javascript
JavaScript实现格式化字符串函数String.format
2016/12/16 Javascript
vue2 自定义动态组件所遇到的问题
2017/06/08 Javascript
详解用函数式编程对JavaScript进行断舍离
2017/09/18 Javascript
基于javascript 显式转换与隐式转换(详解)
2017/12/15 Javascript
原生js实现Flappy Bird小游戏
2018/12/24 Javascript
vue的for循环使用方法
2019/02/12 Javascript
微信小程序iBeacon测距及稳定程序的实现解析
2019/07/31 Javascript
vue中使用vue-print.js实现多页打印
2020/03/05 Javascript
vue中可编辑树状表格的实现代码
2020/10/31 Javascript
[48:00]EG vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.26
2018/08/29 DOTA
Python中遇到的小问题及解决方法汇总
2017/01/11 Python
Python实现的生成格雷码功能示例
2018/01/24 Python
python PIL/cv2/base64相互转换实例
2020/01/09 Python
Python字典fromkeys()方法使用代码实例
2020/07/20 Python
localStorage 设置过期时间的方法实现
2018/12/21 HTML / CSS
调用HTML5的Canvas API绘制图形的快速入门指南
2016/06/17 HTML / CSS
导出HTML5 Canvas图片并上传服务器功能
2019/08/16 HTML / CSS
美国单身专业人士在线约会网站:EliteSingles
2019/03/19 全球购物
实习老师个人总结的自我评价
2013/09/28 职场文书
大型活动策划方案
2014/01/12 职场文书
晚会开幕词范文
2016/03/04 职场文书
python异常中else的实例用法
2021/06/15 Python