smarty模版的核心思想:把数据和显示界面分离
那开始写我们自己的smarty类:MyMiniSmarty.class.php
目的:把模版(*.tpl)中的占位符替换为可以在服务器执行的文件(编译过后的*.php)。
需要替换的模版文件:test.tpl
代码如下:
<html> <head> <title>{$title}</title> </head> <body> <h1>我的网站</h1> {$content}
</body> </html>
我们希望通过MyMiniSmarty.class.php编译后的文件com_test.php代码如下:
<html> <head> <title><?php echo $this->tpl_vars["title"] ?></title> </head> <body> <h1>我的网站</h1> <?php echo $this->tpl_vars["content"] ?> </body> </html>
为了达到上面的要求,我们开始真正编写MyMiniSmarty.class.php
代码如下:
<?php class MyMiniSmarty{ //我们的模版文件夹路径 var $template_dir = "./templates/"; //编译后的文件夹路径 var $compile_dir = "./templates_c/"; //存放获取的数据 var $tpl_vars = array(); //这里我们仿照Smarty模版技术,主要模拟assign 和 display 两个方法 //这个assign 方法比较简单,只是把传递过来的值存起来 function assign($tpl_var, $val){ if($tpl_var != ''){ $this->tpl_vars[$tpl_var] = $val; } } //这里编写display方法,这个是的大头,拿下这个就能完全理解Smarty模版技术核心了 function display($tpl_file){ //读取这个模版文件-->替换为可以运行的php(即编译后的文件) $tpl_file_path = $this->template_dir.$tpl_file; $compile_file_path = $this->compile_dir."com_".$tpl_file.".php"; //判断文件是否存在 if(!file_exists($tpl_file_path)){ return false; } //这里我们要考虑深一点,没有必要每次都来编译一次,可能模版文件并没有改变,所有我们在这里做个判断 if(!file_exists($compile_file_path) || filemtime($tpl_file_path) > filemtime($compile_file_path)) { //获取模版文件内容 $tpl_file_content = file_get_contents($tpl_file_path); //这里用到了正则表达式技术,主要调用 preg_replace 方法 ,这里大家可以把这个替换封装成一个方法,这里就直接给出具体过程 $pattern = array( '/\{\s*\$([a-zA-Z_][a-zA-Z0-9_]*)\s*\}/i' ); $replace = array( '<?php echo $this->tpl_vars["${1}"] ?>' ); $newStr = preg_replace($pattern, $replace, $tpl_file_content); //把替换后的内容,存到编译文件夹下 file_put_contents($compile_file_path, $newStr); } //最后引入这个编译后的文件 include $compile_file_path; } } ?>
调用的代码如下myController.php
<?php require_once 'MyMiniSmarty.class.php'; $smarty = new MyMiniSmarty(); $smarty->assign("title", "Testing"); $smarty->assign("content", "Hello, world"); $smarty->display("test.tpl"); ?>
最后效果图如下(已测试):