我们为大家收集整理了关于PHP的自定义模板引擎,以方便大家参考。什么是网站模板?准确地说,是指网站页面模板,即每个页面仅是一个板式,包括结构、样式和页面布局,是创建网页内容的样板,也可以理解为已有的网页框架。可以将模板中原有的内容替换成从服务器端数据库中动态内容,目的是可以保持页面风格一致
概述
PHP是一种html内嵌式的在服务器端执行的脚本语言,所以大部分PHP开发出来的web应用,初始的开发模板就是混合层的数据编程。虽然通过MVC设计模式可以把程序应用逻辑与网页呈现逻辑强制性分离,但也只是将应用程序的输入、处理和输出分开,网页呈现逻辑(视图)还会有HTML代码和PHP程序强耦合在一起。PHP脚本的编写者必须既是网页设计者,又是PHP开发者
现在已经有很多解决方案,可以将网站的页面设计和PHP应用程序几乎完全分离。这些解决方案称为“模板引擎”,它们正在逐步消除由于缺乏层次分离而带来的难题。模板引擎的目的,就是要达到上述提到的逻辑分离的功能。它能让程序开发者专注于资料的控制或是功能的达成。因此,模板引擎很适合公司的Web开发团队使用,使每个人都能发挥其专长
模板引擎技术的核心比较简单。只要将前端页面指定为模板文件,并将这个模板文件中动态的内容,如数据库输出、用户交互等部分,定义成使用特殊“定界符”包含的“变量”,然后放在模板文件中相应的位置。当用户浏览时,由PHP脚本程序打开该模板文件,并将模板文件中定义的变量进行替换。这样,模板中的特殊变量被替换为不同的动态内容时,就会输出需要的页面
目前,可以在PHP中应用的并且比较成熟的模板有很多,例如Smarty、PHPLIB、IPB等几十种。使用这些通过PHP编写的模板引擎,可以让代码脉络更加清晰,结构更加合理化。也可以让网站的维护和更新变得更容易,创造一个更加良好的开发环境,让开发和设计工作更容易结合在一起。但是,没有哪一个PHP模板是最合适、最完美的。因为PHP模板就是大众化的东西,并不是针对某个人开发的。如果能在对模板的特点、应用有清楚的认识基础上,充分认识到模板的优势劣势,就可以知道是否选择使用模板引擎或选择使用哪个模板引擎
自定义模板引擎类
自定义模板引擎,能够更好的掌握模板引擎的工作机制,为学习Smarty做好准备。更重要的是,属于自己的PHP模板引擎永远不是固定不变的,可以根据项目的需要为其量身定制
在下例中,通过前面介绍的模板引擎概念创建了属于自己的一个简单模板引擎,可以用来处理模板的基本功能。例如:变量替换、分支结构、数组循环遍历,以及模板之间相互嵌套等,如下所示:
tpl_vars[$tpl_var] = $value; } /** 加载指定目录下的模板文件,并将替换后的内容生成组合文件存放到另一个指定目录下 @param string $fileName 提供模板文件的文件名 */ function display($fileName) { /* 到指定的目录中寻找模板文件 */ $tplFile = $this->template_dir.'/'.$fileName; /* 如果需要处理的模板文件不存在,则退出并报告错误 */ if(!file_exists($tplFile)) { die("模板文件{$tplFile}不存在!"); } /* 获取组合的模板文件,该文件中的内容都是被替换过的 */ $comFileName = $this->compile_dir."/com_".$fileName.'.php'; /* 判断替换后的文件是否存在或是存在但有改动,都需要重新创建 */ if(!file_exists($comFileName) || filemtime($comFileName) < filemtime($tplFile)) { /* 调用内部替换模板方法 */ $repContent = $this->tpl_replace(file_get_contents($tplFile)); /* 保存由系统组合后的脚本文件 */ file_put_contents($comFileName, $repContent); } /* 包含处理后的模板文件输出给客户端 */ include($comFileName); } /** 内部使用的私有方法,使用正则表达式将模板文件'<{>'中的语句替换为对应的值或PHP代码 @param string $content 提供从模板文件中读入的全部内容字符串 @return $repContent 返回替换后的字符串 */ private function tpl_replace($content) { /* 将左右定界符号中,有影响正则的特殊符号转义 例如,<{>转义\<\{> */ $left = preg_quote($this->left_delimiter, '/'); $right = preg_quote($this->right_delimiter, '/'); /* 匹配模板中各种标识符的正则表达式的模式数组 */ $pattern = array( /* 匹配模板中变量 ,例如,"<{ var="">" */ '/'.$left.'\s*\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*'.$right.'/i', /* 匹配模板中if标识符,例如 "<{ if="" col="="> <{ if="">" */ '/'.$left.'\s*if\s*(.+?)\s*'.$right.'(.+?)'.$left.'\s*\/if\s*'.$right.'/ies', /* 匹配elseif标识符, 例如 "<{ elseif="" col="=">" */ '/'.$left.'\s*else\s*if\s*(.+?)\s*'.$right.'/ies', /* 匹配else标识符, 例如 "<{ else="">" */ '/'.$left.'\s*else\s*'.$right.'/is', /* 用来匹配模板中的loop标识符,用来遍历数组中的值, 例如 "<{ loop="" arrs="" value=""> <{>" */ '/'.$left.'\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*'.$right.'(.+?)'.$left.'\s*\/loop\s*'.$right.'/is', /* 用来遍历数组中的键和值,例如 "<{ loop="" arrs="" key=""> $value }> <{>" */ '/'.$left.'\s*loop\s+\$(\S+)\s+\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*=>\s*\$(\S+)\s*'.$right.'(.+?)'.$left.'\s*\/loop \s*'.$right.'/is', /* 匹配include标识符, 例如,'<{ include="">' */ '/'.$left.'\s*include\s+[\"\']?(.+?)[\"\']?\s*'.$right.'/ie' ); /* 替换从模板中使用正则表达式匹配到的字符串数组 */ $replacement = array( /* 替换模板中的变量 tpl_vars["var"]; */ 'tpl_vars["${1}"]; ?>', /* 替换模板中的if字符串 */ '$this->stripvtags(\'\',\'${2}\')', /* 替换elseif的字符串 */ '$this->stripvtags(\'\',"")', /* 替换else的字符串 */ '', /* 以下两条用来替换模板中的loop标识符为foreach格式 */ 'tpl_vars["${1}"] as $this->tpl_vars["${2}"]) { ?>${3}', 'tpl_vars["${1}"] as $this->tpl_vars["${2}"] => $this->tpl_vars["${3}"]) { ?>${4}', /*替换include的字符串*/ 'file_get_contents($this->template_dir."/${1}")' ); /* 使用正则替换函数处理 */ $repContent = preg_replace($pattern, $replacement, $content); /* 如果还有要替换的标识,递归调用自己再次替换 */ if(preg_match('/'.$left.'([^('.$right.')]{1,})'.$right.'/', $repContent)) { $repContent = $this->tpl_replace($repContent); } /* 返回替换后的字符串 */ return $repContent; } /** 内部使用的私有方法,用来将条件语句中使用的变量替换为对应的值 @param string $expr 提供模板中条件语句的开始标记 @param string $statement 提供模板中条件语句的结束标记 @return strin 将处理后的条件语句相连后返回 */ 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; } }?>
在Mytpl类中声明的多个方法中,除被封装过的方法之外,只有两个公有方法assign()和display()在创建对象以后可以被凋用。其中assign()方法用来将PHP脚本中的数据分配给模板中对应的变量,display()方法则用来将特定的templates目录下的模板文件加载到PHP脚本中。同时将模板文件中使用“<{”和“>>”标记声明的自定义模板语句,匹配出来并替换成相对应的PHP语法格式,然后将替换后的内容保存在特定的templates_c目录下。在运行时还要编译成一个非模板技术的PHP文件,并将其以模板文件名加上“com_”前缀和“.php”的扩展名形式保存。再通过include()函数将处理后的模板文件包含,并使用PHP解析后发送给客户端
来源: http://www.51edu.com/it/bckf/478976.html