自己动手写一个简单的php模板引擎
来源:互联网 发布:js动态添加class属性 编辑:程序博客网 时间:2024/05/21 09:29
模板引擎中最核心的思想是:将模板中的变量编译为php的变量进行输出。
例如:demo.tpl
{$data}{$title}
那么模板引擎就要将{$data} {$title} 编译为 <?php echo $data; ?> <?php echo $title; ?>
要实现这个功能使用正则替换就可以了:
$content = '{$data}{$title}';$pattern = "/\{\$([a-zA-Z_][a-zA-Z0-9_]*)\}/";$content = preg_replace($pattern,'<?php echo \$this->tmpValue["$1"] ?>',$content);echo $content; // <?php echo $data; ?><?php echo $title; ?>
这就是php模板引擎的核心功能了。下面是我写的一个简单的php模板引擎
首先是tempTool.class.php 它的作用的提供模板引擎需要用到的一些小工具
<?php/** * 工具类 **/class tempTool{protected $error = array();//错误信息function __construct(){}/** * 生成错误日志数组 **/ protected function error($k,$v) { if(!empty($k) && !empty($v)) { $this->error[$k] = $v; }else { exit('tempTool.class.php的error方法收到了不确定的参数错误!'); } } /** * 获取错误信息 **/ public function getError() { foreach($this->error as $k=>$v) { echo $k.$v.'<br />'; } }}?>
然后是template.class.php 它的作用是提供模板引擎应该有的功能
<?php/** * 模板引擎类 用语提供模板引擎应该具有的方法 **/include_once "tempTool.class.php";class template extends tempTool{private $config = array('tmpDir'=>'template/',// 模板文件目录'cmpDir'=>'compile/',// 编译文件目录'cacheDir'=>'cache/',// 缓存文件目录'tmpSuffix'=>'.tpl',// 模板文件后缀'cacheSuffix'=>'.html',// 缓存文件后缀'caching'=>false// 是否开启缓存);private $tmpFile;// 模板文件private $cmpFile;// 编译文件private $cacheFile;// 缓存文件private $tmpValue = array();// 变量值栈public function __construct($config = null){// 同步配置if(is_array($config)) {$this->config = array_merge($this->config,$config);}// 检查模板编译缓存目录是否存在不存在创建if( !$this->checkDir($this->config['tmpDir']) || !$this->checkDir($this->config['cmpDir']) || !$this->checkDir($this->config['cacheDir']) ) {exit;}}/** * 检查目录是否存在不存在自动创建 **/private function checkDir($dir){if(!is_dir($dir)) {if(!mkdir($dir)) {$this->errorLog[] = array('创建文件夹失败:'=>$dir);return false;}}return true;}/** * 像模板中分配变量 * **/public function assign($k,$v){if(!empty($k) && !empty($v)) {$this->tmpValue[$k] = $v;}else {$this->error('分配变量失败:','分配到模板中变量的key或者value为空!');}}/** * 编译文件 **/public function display($tmpFile){// 获取模板文件$tmpFile = $this->config['tmpDir'].$tmpFile.$this->config['tmpSuffix'];// 获取编译文件$cmpFile = $this->config['cmpDir'].md5($tmpFile.'compile').'.php';if(!file_exists($tmpFile)) {$this->error('模板文件不存在:',$tmpFile.'不存在');}// 当编译文件不存在或者是模板文件被修改过了才重新编译if(!file_exists($cmpFile) || filemtime($cmpFile) < filemtime($tmpFile)) {include_once "compile.class.php";$cmp = new compile();$cmp->cmp($tmpFile,$cmpFile);}// 是否开启缓存if($this->config['caching']) {// 获取缓存文件$cacheFile = $this->config['cacheDir'].md5($tmpFile.'cache').$this->config['cacheSuffix'];// 当缓存文件不存在或者是模板文件被修改过重新生成缓存文件if(!file_exists($cacheFile) || filemtime($cacheFile) < filemtime($tmpFile)) {ob_start();include_once $cmpFile;$content = ob_get_clean();if(!file_put_contents($cacheFile,$content)){$this->error('编译文件生成失败:',$cacheFile);}}//载入缓存文件 include $cacheFile;}else {// 载入编译文件include_once $cmpFile;}}}
compile.class.php 编译类将模板文件编译为php文件
<?php/** * 编译类将模板文件编译为php文件 **/include_once "tempTool.class.php";class compile extends tempTool{private $content; // 文件编译后的内容/** * 将模板文件编译php文件 **/function cmp($tmpFile,$cmpFile){if(!($content = file_get_contents($tmpFile))){$this->error("文件读取失败:",$tmpFile);}$pattern = "/\{\\$([a-zA-Z_][a-zA-Z0-9_]*)\}/";$this->content = preg_replace($pattern,'<?php echo \$this->tmpValue["$1"] ?>',$content);$this->parse($cmpFile);}/** * 将编译好的内容写入文件 **/public function parse($cmpFile){if(!file_put_contents($cmpFile,$this->content)){$this->error('文件写入失败:',$cmpFile);}}}?>
下面进行一下测试:
1. 新建一个 template 文件夹 在里面写 一个模板 demo.tpl
{$data}{$title}2.新建一个demo.php
<?php$config = array('caching'=>true);include_once "template.class.php";$tmp = new template($config);$tmp->assign('data','ccc');$tmp->assign('title','这时测试用例');$tmp->display('demo');
结果输出 ccc这时测试用例
可以看一下cache目录和 compile目录下 会生成一个缓存文件 和一个编译文件
这时就成功了
- 自己动手写一个简单的php模板引擎
- 写了一个简单实用的PHP模板引擎
- 一个自己写的PHP模板引擎
- php 编写一个简单的模板引擎
- 自己动手写一个简单的bootloader
- 一个简单的模板引擎
- 自己动手写一个轻巧,高效的正则表达式引擎
- 自己写的一个jquery模板引擎
- php简单的自定义模板引擎类。
- PHP 实现简单的模板引擎
- 写了一个最简单的 js 模板引擎,直接贴代码
- 分享一个简单的python模板引擎
- 自己动手写一个简单的Shell之一:了解Shell
- 自己动手写一个简单的Shell之二:运行程序
- 自己动手写一个简单的Shell之三:命令行解析
- 自己动手写一个简单的Shell之四:流程控制
- 自己动手写一个简单的Windows shell扩展程序
- 自己动手写一个简单的MVC框架(第一版)
- Linux设备驱动之I/O端口与I/O内存
- JNI学习积累之二 ---- 数据类型映射、域描述符说明
- HDU 3689 Infinite monkey theorem (uva11468)ac自动机+dp
- android动画坐标定义
- 纪一次笔试之行—燃烧的远征
- 自己动手写一个简单的php模板引擎
- 试探讨暴风影音2014笔试题
- 绩效考核系统开发心得之三__数据库操作
- For-each循环访问多维数组
- 【高精】wikioi 1087 麦森数 (noip2003)
- IOS之触摸事件和手势
- Xcode创建子工程以及工程依赖
- 解决PowerDesigner中DBMS设置的问题
- 多态是如何实现的