我的完全面向对象的简单模板引擎
以前写的一个模板引擎,思路源于discuz
现在有空整理出来与大家交流交流
示例文件下载
<?php
/**
* 简单模板类
*
* 流水孟春 121169238@qq.com
* 大家给给意见和建议
*
*/
class View {
/**#@+
* View Configuration Section
*/
public $template_dir = 'templates/default/';
public $template_suffix = '.htm'; // 模板的后缀
public $compiled_dir = 'templates/compiled/';
public $compiled_suffix = '.tpl.php'; // 编译后模板的后缀
public $compile_check = true; // 在这个模板引擎中作用不大,
public $force_compile = true;
public $left_delimiter = '{';
public $right_delimiter = '}';
const VERSION = 0.1;
/**#@+
* END View Configuration Section
* There should be no need to touch anything below this line.
* @access private
*/
private $_tpl_vars = array();
private $_resource_name = null;
private $_compiled_id = '';
private $_resource_file = null;
private $_compiled_file = null;
/**#@-*/
/**
* 调用模板
* @param string $resource_name 输入框名称
* @param string $compiled_id 模板编译id
*/
public function display($resource_name, $compiled_id = null){
if (isset($compiled_id)) {
$this->_compiled_id = $compiled_id; // 设置模板
}
$this->_resource_name = $resource_name; // 设置模板名
$this->_resource_file = $this->template_dir . $this->_resource_name; // 模板路径
$this->_compiled_file = $this->compiled_dir . $this->_compiled_id . '^'
. $this->_resource_name . $this->compiled_suffix; // 模板编译成的文件
if(($this->force_compile) || !file_exists($this->_compiled_file)) {// 如果编译后的文件不存在
$this->_parse($this->_resource_file, $this->_compiled_file);
} elseif ($this->compile_check){
if (filemtime($this->_resource_file) >= filemtime($this->_compiled_file)) { // 如果文件被更改过则更新
$this->_parse($this->_resource_file, $this->_compiled_file);
}
}
require $this->_compiled_file;
}
/**
* 模板变量赋值
*
* @param mixed $tpl_var 变量名
* @param mixed $value 变量的值
*/
public function assign($tpl_var, $value = null) {
if (is_array($tpl_var)){
foreach ($tpl_var as $key => $val) {
if ($key != '') {
$this->_tpl_vars[$key] = $val;
}
}
} else {
if ($tpl_var != '')
$this->_tpl_vars[$tpl_var] = $value;
}
}
/**
* 编译模板
*
*/
private function _parse($resource, $compiled) {
if(!@$fp = fopen($resource, 'r')) {
die("Current template file '" . str_replace('\\', '/', getcwd()) . "/$resource' not found or have no access!");
}
$template = fread($fp, filesize($resource));
fclose($fp);
$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]*\{import\s+([a-z0-9_]+)\}[\n\r\t]*/ies","trim(self::_import('$this->template_dir\\1$this->template_suffix'))", $template);
$template = preg_replace("/[\n\r\t]*\{import\s+(.+?)\}[\n\r\t]*/ies", "trim(self::_import('$this->template_dir\\1$this->template_suffix'))", $template);
$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template); // 每行前面的空格都去掉
$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template); // 把<!--{xx}--> 中的<!--和-->去掉
$template = preg_replace("/\{(if.+?)\}/s", "{\\1 }", $template); // 把 {if $xx} => {if $xx } 为了使$xx可以是$xx['xx']
file_put_contents('xx3.php',$template);
$template = preg_replace("/\{\\\$$const_regexp\.$const_regexp\}/s", "<?=$this->_tpl_vars['\\1']['\\2']?>", $template); // 把 {$xx.xx} => <?=$this->_tpl_vars['xx']['xx'] ? >
$template = preg_replace("/\{\\\$$const_regexp\.$const_regexp\.$const_regexp\}/s", "<?=$this->_tpl_vars['\\1']['\\2']['\\3']?>", $template); // 把 {$xx.xx.xx} => <?=$this->_tpl_vars['xx']['xx']['xx'] ? >
$template = preg_replace("/\{\\\$([a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=$this->_tpl_vars['\\1']?>", $template); // {$var} => <?=$this->_tpl_vars['var'] ? >
$template = preg_replace("/\<\?\=\<\?\=(([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)\?\>\?\>/es", "self::_add_quote('<?=\\1?>')", $template); // <?=?=string ? >? > => <?=string ? >
$template = preg_replace("/[\n\r\t]*\{elseif\s+\\\$$const_regexp(.+?)\}[\n\r\t]*/ies", "self::_strip_tags('\n<?php elseif($this->_tpl_vars[\'\\1\']\\2) : ?>\n','')", $template); //<!--{elseif}--> ...
$template = preg_replace("/[\n\r\t]*\{else\}[\n\r\t]*/is", "\n<?php else : ?>\n", $template); //<!--{else}--> ...
for($i = 0; $i < 5; $i++) {
$template = preg_replace("/[\n\r\t]*\{loop\s+\\\$(\S+)\s+\\\$(\S+)\}[\n\r]*(.+?)[\n\r]*\{\/loop\}[\n\r\t]*/ies", "self::_strip_tags('\n<?php if(is_array($this->_tpl_vars[\'\\1\']) ) : \n foreach($this->_tpl_vars[\'\\1\'] as $this->_tpl_vars[\'\\2\']) : ?>','\n\\3\n<?php endforeach; endif; ?>\n')", $template); // loop => foreach
$template = preg_replace("/[\n\r\t]*\{loop\s+\\\$(\S+)\s+\\\$(\S+)\s+\\\$(\S+)\}[\n\r\t]*(.+?)[\n\r\t]*\{\/loop\}[\n\r\t]*/ies", "self::_strip_tags('\n<?php if(is_array($this->_tpl_vars[\'\\1\'])) : \n foreach($this->_tpl_vars[\'\\1\'] as $this->_tpl_vars[\'\\2\'] => $this->_tpl_vars[\'\\3\']) : ?>','\n\\4\n<?php endforeach; endif; ?>')", $template); // loop => foreach too
$template = preg_replace("/[\n\r\t]*\{if\s+(.?)\\\$$const_regexp(.+?)\}[\n\r]*(.+?)[\n\r]*\{\/if\}[\n\r\t]*/ies", "self::_strip_tags('\n<?php if(\\1$this->_tpl_vars[\'\\2\']\\3) : ?>','\n\\4\n<?php endif; ?>\n')", $template); // <!--{if $cat--> => <?php if($cat) { ? >
}
$template = preg_replace("/\{$const_regexp\}/s", "<?=\\1?>", $template); //{CONST} => <?=CONST ? >
$template = preg_replace("/ \?\>[\n\r]*\<\?php /s", " ", $template); // ? ><?php => ""
$template = preg_replace("/[\n\r\t]*\{attr\s+([a-z0-9_]+)\}[\n\r\t]*/is","<?php print_r(\$this->\\1) ?>", $template); // 输出模板变量 {attr left_delimiter} => {
if(!@$fp = fopen($compiled, 'w')) {
die("Directory '" . str_replace('\\', '/', getcwd()) . "/$this->_compiled_file' not found or have no access!");
}
$template = preg_replace("/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/e", "self::_trans_amp('\\0')", $template);
$template = preg_replace("/\<script[^\>]*?src=\"(.+?)\".*?\>\s*\<\/script\>/ise", "_strip_script_amp('\\1')", $template);
$template = "<?php if(!defined('IN_MENG')) exit('Access Denied'); ?>\n$template";
$template = str_replace('$this->_tpl_vars', '$this->_tpl_vars', $template);
flock($fp, 2);
fwrite($fp, $template);
fclose($fp);
}
private static function _trans_amp($str) {
$str = str_replace('&', '&', $str);
$str = str_replace('&amp;', '&', $str);
$str = str_replace('\"', '"', $str);
return $str;
}
private static function _add_quote($var) {
return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
}
private static function _strip_tags($expr, $statement) {
$expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));
$statement = str_replace("\\\"", "\"", $statement);
return $expr.$statement;
}
private static function _strip_script_amp($s) {
$s = str_replace('&', '&', $s);
return "<script src=\"$s\" type=\"text/javascript\"></script>";
}
/**
*
*/
private static function _import($resource){
if(!@$fp = fopen($resource, 'r')) {
die("Current template file '$resource' not found or have no access when import it!");
}
$content = fread($fp, filesize($resource));
fclose($fp);
return $content;
}
public function __get($att) {
return $this->$att;
}
}
?>