PHP模板解析类实例模板解析类实例
主要介绍了PHP模板解析类,涉及php针对模板文件的解析与字符串处理的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
本文实例讲述了PHP模板解析类。分享给大家供大家参考。具体如下:
<?php
class template {
private $vars = array();
private $conf = '';
private $tpl_name = 'index';
//如果模板不存在 会查找当前 controller默认index模板
private $tpl_suffix = '.html';//如果CONFIG没配置默认后缀 则显示
private $tpl_compile_suffix= '.tpl.php';//编译模板路径
private $template_tag_left = '<{';//模板左标签
private $template_tag_right = '}>';//模板右标签
private $template_c = '';//编译目录
private $template_path = '';//模板完整路径
private $template_name = '';//模板名称 index.html
//定义每个模板的标签的元素
private $tag_foreach = array('from', 'item', 'key');
private $tag_include = array('file');//目前只支持读取模板默认路径
public function __construct($conf) {
$this->conf = &$conf;
$this->template_c = $this->conf['template_config']['template_c'];//编译目录
$this->_tpl_suffix = $this->tpl_suffix();
}
private function str_replace($search, $replace, $content) {
if(empty($search) || empty($replace) || empty($content)) return false;
return str_replace($search, $replace, $content);
}
/**
* preg_match_all
* @param $pattern 正则
* @param $content 内容
* @return array
*/
private function preg_match_all($pattern, $content) {
if(empty($pattern) || empty($content)) core::show_error('查找模板标签失败!');
preg_match_all("/".$this->template_tag_left.$pattern.$this->template_tag_right."/is", $content, $match);
return $match;
}
/**
* 模板文件后缀
*/
public function tpl_suffix() {
$tpl_suffix = empty($this->conf['template_config']['template_suffix']) ?
$this->tpl_suffix :
$this->conf['template_config']['template_suffix'] ;
return $tpl_suffix;
}
/**
* 此处不解释了
* @return
*/
public function assign($key, $value) {
$this->vars[$key] = $value;
}
/**
* 渲染页面
* @param
* 使用方法 1
* $this->view->display('error', 'comm/');
* 默认是指向TPL模版的跟目录,所以comm/就是 tpl/comm/error.html
* 使用方法 2
* $this->view->display('errorfile');
* 默认指向控制器固定的文件夹
* 例如你的域名是 http://heartphp/admin/index, 那么正确路径就是tpl/admin/index/errorfile.html
* @return
*/
public function display($filename = '', $view_path = '') {
$tpl_path_arr = $this->get_tpl($filename, $view_path);//获取TPL完整路径 并且向指针传送路径以及名称
if(!$tpl_path_arr) core::show_error($filename.$this->_tpl_suffix.'模板不存在');
//编译开始
$this->view_path_param = $view_path;//用户传递过来的模版跟目录
$this->compile();
}
/**
* 编译控制器
* @param
* @return
*/
private function compile() {
$filepath = $this->template_path.$this->template_name;
$compile_dirpath = $this->check_temp_compile();
$vars_template_c_name = str_replace($this->_tpl_suffix, '', $this->template_name);
$include_file = $this->template_replace($this->read_file($filepath), $compile_dirpath, $vars_template_c_name);//解析
if($include_file) {
$this->read_config() && $config = $this->read_config();
extract($this->vars, EXTR_SKIP);
[url=home.php?mod=space&uid=48608]@include[/url] $include_file;
}
}
/**
* 读取当前项目配置文件
*/
protected function read_config() {
if(file_exists(SYSTEM_PATH.'conf/config.php')) {
@include SYSTEM_PATH.'conf/config.php';
return $config;
}
return false;
}
/**
* 解析模板语法
* @param $str 内容
* @param $compile_dirpath 模版编译目录
* @param $vars_template_c_name 模版编译文件名
* @return 编译过的PHP模板文件名
*/
private function template_replace($str, $compile_dirpath, $vars_template_c_name) {
if(empty($str)) core::show_error('模板内容为空!');
//处理编译头部
$compile_path = $compile_dirpath.$vars_template_c_name.$this->tpl_compile_suffix;//编译文件
if(is_file($compile_path)) {
//$header_content = $this->get_compile_header($compile_path);
//$compile_date = $this->get_compile_header_comment($header_content);
$tpl_filemtime = filemtime($this->template_path.$this->template_name);
$compile_filemtime = filemtime($compile_path);
//echo $tpl_filemtime.'=='.date('Y-m-d H:i:s', $tpl_filemtime).'<br/>';
//echo $compile_filemtime.'=='.date('Y-m-d H:i:s', $compile_filemtime);
//如果文件过期编译 当模板标签有include并且有修改时 也重新编译
//<{include file="public/left.html"}> 当修改include里的文件,非DEBUG模式时 如果不更改主文件 目前是不重新编译include里的文件,我在考虑是否也要更改,没想好,暂时这样,所以在开发阶段一定要开启DEBUG=1模式 要不然修改include文件无效 。 有点罗嗦,不知道表述清楚没
if($tpl_filemtime > $compile_filemtime || DEBUG) {
$ret_file = $this->compile_file($vars_template_c_name, $str, $compile_dirpath);
} else {
$ret_file = $compile_path;
}