文章目录
1. Smarty介绍
1.1. 什么是Smarty
Smarty是模板引擎技术之一。所谓的模板引擎就是为了使应用程序的业务逻辑(PHP代码)和表示逻辑(HTML代码)进行分离,从而达到程序员只关心程序的编写,而美工人员进行页面的设计的目的。
模板:html+css。
意思:可以使得"php代码"与"html代码"分离的技术都称为模板引擎技术。
1.2. 为什么需要Smarty
从团队的角度出发,它可以提高工作效率,php程序员只负责编写后台的php代码,获取数据,将数据分配给前台,美工人员或者说前端开发人员就只负责写html,css,js这些,同时需要将后台分配过来的数据进行展示,而模板引擎就是后台和前台之间的桥梁。它的出现就是让二者的工作合二为一,因为前端人员可能不懂php代码,而还要将后台传过来的数据进行展示,所以不可避免的要用到php代码,比如,如下:
上图php和html代码混写。$title是一个变量,它的值就是要从后台获取,此处是用php代码来把它输出出来,那么模板引擎smarty处于对前端人员的考虑,会有一个特殊符号代替php代码,如上图的<?php echo
和结尾的;?>
。
总归一句话,后端和前端各司其职,互不干扰,而前端你不是不懂php吗,没关系,有smarty,你只需要记住smarty的特殊符号即可,smarty模板引擎自动会转换。
1.3. Smarty的特点
- 强大的表现逻辑:Smarty提供了适当的构造(比如if,foreach啊这些),能够有条件地计算和迭代处理数据,虽然它本身实际上是一种语言,但语法简单,设计人员可以很快地学会,而不需要预备的编程知识。
- 模板编译:为减少开销,Smarty在默认情况下将模板转换为可比较的PHP脚本(php+html的混编文件),使得后续的调用速度更快(在下一次访问目标时直接访问编译好的文件,从而不再进行模板的重新编译)。Smarty还非常智能,在内容改变后可以重新编译。
- 缓存:Smarty还提供了缓存模板的可选择性,缓存与编译不同的是,支持缓存不只是能生成缓存的内容,还能防止执行个别逻辑。例如,你可以指定缓存文档的生存时间,比如5分钟,在此期间可以忽略与该模板有关的数据库查询。缓存文件是在编译好的文件也就是混编文件上出来的。
- 高度可配置和可扩展:Smarty的面向对象架构允许修改和扩展其默认行为,此外,从一开始可配置性就是一个设计目标,为用户提供了很大的灵活性,通过内置方法和属性定制Smarty的行为。说白了,就是Smarty内部包含了内置的插件,这些插件就是一个个函数,这些函数都是完成某种特定功能,比如截取字符串。可扩展的意思就是Smarty没有我们想要的功能,我们可以自定义一个函数。
- 安全:Smarty提供了很多安全特性,可以避免服务器和应用程序数据遭到设计人员有意或无意的破坏。
1.4. Smarty大致流程图
要点:PHP文件+tpl文件(html)+混合php+html文件(编译文件)
2. 自定义模板引擎
2.1. 思路讲解
新建一个index.php文件
<?php
$title="静夜思";
$content="床前明月光,疑是地上霜,举头望明月,低头思故乡";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div><?php echo $title; ?></div>
<div><?php echo $content; ?></div>
</body>
</html>
上面php代码和html混合在一起,不好维护,不利于团队协作,按照规范,php代码是php的,html是html的,也就是说,逻辑层和表现层要分离开来,程序员和美工各写各的,写完再整合。
所以我们再新建一个index.html文件。也就是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div><?php echo $title; ?></div>
<div><?php echo $content; ?></div>
</body>
</html>
那么index.php就是:
<?php
$title="静夜思";
$content="床前明月光,疑是地上霜,举头望明月,低头思故乡";
require “index.html”;
?>
很显然,当我们再次访问index.php的时候,就应该要把index.html包含进来,很简单,就是require “index.html”; 在基础语法已经学过了。
但是,我们观察index.html文件中,作为美工的角度去看,我是一个美工人员,并不懂php代码。我的关注点在于页面的美化上。所以说,你页面上要输出$title和$content是不是用到了PHP代码的定界符和echo语句。所以,为了方便美工人员,我们就把变量前的<?php echo
和变量后的; ?>
去掉,去掉就剩了变量本事,但是,还是得要求美工人员,在变量前后要加上花括号。比如:{$title}。就表示要把$title这个变量输出出来。不然就会以为你是一个字符串,就会原样输出。美工人员虽然不会PHP,但是简单的花括号还是会的。对应了上图表现层右边的黑色字体的解释。
所以index.html就变成了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>{$title}</div>
<div>{$content}</div>
</body>
</html>
但是这样去访问,效果肯定不对,你还没有对花括号进行处理呢,系统怎么会知道你那花括号就是要输出PHP代码的?所以它会原样输出就是{$title}和{$content}。那怎么才会输出呢,肯定是要变回原来的echo啦!也就是说,要有一个工具,来对美工人员写的html页面中的花括号进行解析,解析成原来的风格。怎么一个解析发,首先,我们可以运用我们在基础篇学的替换语法,让{
替换为<?php echo
,再让}
替换为; ?>
。这个工具就是模板引擎了,因为是自定义模板引擎,所以此处模板引擎是我们自己写,来感受一下。
最后生成出来的我们单独给它放到一个文件中,后缀就是.html.php。起名比如idx.html.php。就可以看出来它是一个混编文件。上面的index.html是模板文件。中间的模板引擎也得有一个具体的文件来完成它的替换功能,它是一个类,起名为MiniSmarty.class.php,这个类是一个工具,是共用的。
<?php
//模板引擎类
class MiniSmarty{
//编译模板文件(将花括号替换为php标记)
function compile($tpl){
//获得模板文件内部具体的模板内容
$cont = file_get_contents($tpl);
//获取index.html的内容,结果是
//echo $cont;
//效果如下
/*{$title}
{$content}*/
//是不是用file_get_contents把html的内容读取出来,用字符串的形式输出,展示在浏览器上,就形成了上面的效果。
//替换:“{” --> “< ?php echo” “}“ --> ”? >”
$cont = str_replace("{", "<?php echo ", $cont);
$cont = str_replace("}", "; ?>", $cont);
echo $cont;//页面没有任何显示,右击打开源代码,发现已经替换内容。为什么页面没内容呢?
//是因为你echo 出来的$cont是一个字符串
//把它输出来的信息放到一个文件(php+html的混编内容)即可,然后require进来
file_put_contents("idx.html.php",$cont);//如果文件没有,自动创建
//再引入混编文件
require 'idx.html.php';
}
}
注意idx.html.php是可以自动创建的,写好了功能类,接下来就是要在index.php中去调用类中的函数,完成替换功能。
<?php
$title="静夜思";
$content="床前明月光,疑是地上霜,举头望明月,低头思故乡";
//下面这样直接require包含index.html是不行的,因为它的花括号并没有被处理,所以要把它注释掉
//require "index.html";
//得把index.html里面的内容换成真正的php的内容。
//所以,要引入MiniSmarty.class.php,它是一个类,所以我们要new它
require "MiniSmarty.class.php";
//类中有个替换功能,要想调用,必须实例化。
$smarty = new MiniSmarty();
//调用类中的compile函数,完成替换功能,那么传进去的参肯定是你要替换的那个页面。
$smarty->compile("index.html");
?>
也就是说,美工写的模板页面,最终会被模板引擎解释成上面的样子,就是idx.html.php,最终展示在浏览器的就是idx.html.php。但是结果却是报变量未定义,如下图:
为什么呢?因为它是局部变量,它是不是在函数里,它能不能访问到函数外部的变量?肯定不能。现在是解决上面变量未定义的问题:第一反应,就是在函数里加global,但很明显,不行。哪解决办法是什么?可以把模板引擎内部使用的变量信息都声明为该"模板类"的属性信息,这样在类的内部可以正常使用本身的属性信息。所以,在类里部加几句代码,如下:
public $tpl_var = array();
function assign($k,$v){
$this->tpl_var[$k]=$v;
}
那么,在index.php中,就要调用assign方法,如下:
$smarty -> assign("title",$title);
$smarty -> assign("content",$content);
类中的替换也要有所改变:
$cont = str_replace('{$', '<?php echo $this->tpl_var["', $cont);
$cont = str_replace('}', '"]; ?>', $cont);
2.2. 完整代码
index.php:
<?php
$title="静夜思";
$content="床前明月光,疑是地上霜,举头望明月,低头思故乡";
//下面这样直接require包含index.html是不行的,因为它的花括号并没有被处理,所以要把它注释掉
//require "index.html";
//得把index.html里面的内容换成真正的php的内容。
//所以,要引入MiniSmarty.class.php,它是一个类,所以我们要new它
require "MiniSmarty.class.php";
//类中有个替换功能,要想调用,必须实例化。
$smarty = new MiniSmarty();
$smarty -> assign("title",$title);
$smarty -> assign("content",$content);
//调用类中的compile函数,完成替换功能,那么传进去的参肯定是你要替换的那个页面。
$smarty->compile("index.html");
?>
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>{$title}</div>
<div>{$content}</div>
</body>
</html>
MiniSmarty.class.php:
<?php
//模板引擎类
class MiniSmarty{
//给该类声明属性,用于存储外部的变量信息
public $tpl_var = array();
//把外部变量设置为类内部属性的一部分
function assign($k,$v){
$this->tpl_var[$k]=$v;
}
//编译模板文件(将花括号替换为php标记)
function compile($tpl){
//获得模板文件内部具体的模板内容
$cont = file_get_contents($tpl);
//获取index.html的内容,结果是
//echo $cont;
//效果如下
/*{$title}
{$content}*/
//是不是用file_get_contents把html的内容读取出来,用字符串的形式输出,展示在浏览器上,就形成了上面的效果。
//替换:“{” --> “< ?php echo” “}“ --> ”? >”
$cont = str_replace('{$', '<?php echo $this->tpl_var["', $cont);
$cont = str_replace('}', '"]; ?>', $cont);
//echo $cont;//页面没有任何显示,右击打开源代码,发现已经替换内容。为什么页面没内容呢?
//是因为你echo 出来的$cont是一个字符串
//把它输出来的信息放到一个文件(php+html的混编内容)即可,然后require进来
file_put_contents("idx.html.php",$cont);//如果文件没有,自动创建
//再引入混编文件
require "idx.html.php";
}
}
3. 模板引擎的优化
1.混编文件一旦生成好,不要反复生成,直接引入即可。解决思路就是给每个应用都生成一个唯一的混编文件,执行之前先判断是否存在,如果存在就直接引入,否则再生成。
2.但是缺陷也来了,如果我index.html增加了一个变量呢?你index.php再访问它就访问到原来的index.html.php文件,而不是新的php文件,也就是说,模板文件如果有修改的话,混编文件就得重新生成。所以,这要在怎么判断?
答案是通过时间来判断,比如我们是先有模板文件index.html再有index.html.php混编文件,所以混编文件的时间是大于模板文件的时间,如果有一天模板文件的时间大于了混编文件的时间,就说明混编文件不是最新的,模板文件产生了修改,这时候就要重新生成混编文件了。如下:
//1. 该混编文件必须存在
//2. 混编文件的修改时间 大于 模板文件的修改时间
// 就直接走混编文件,不用重新生成。
if(file_exists($com_file) && filemtime($com_file) > filemtime($tpl)){
require $com_file;
}else{
.....
}
3.如图:
是不是发现这样存放的话像混编文件和模板文件这些都混杂在一起,不好看,应该建立一个文件夹,一个文件夹专门放模板文件,一个文件夹专门放混编文件,这样分类存储,即美观,也好管理。新建一个文件夹叫view,专门存放模板文件,再新建一个文件夹叫view_c,专门存放混编文件。
4. 现在上面已经很完美了,功能也实现了,不过上面compile,译为编译,有点底层,我们可以再写一个方法叫display,display翻译叫显示,显示嘛,更你体现表明的意思,用来展现模板,容易理解,所以:
相应的,index.php调用的方法名从compile要改为display。
总结:
注意,最后交给浏览器的是混编文件的内容。并且模板文件不允许出现php代码,只允许出现模板标记,比如花括号,否则将原样输出,php代码不会被解析。
4. 成熟模板引擎使用
4.1. 下载Smarty
打开该官网 https://www.smarty.net/ :如图
这里我就选择3.1.34版本的。就是 smarty-3.1.34.zip。解压该目录:
demo文件夹是例子。libs文件夹是资源库。最核心,最主要的文件都在这里面了。点进去:
当中有Smarty.class.php文件,说明它是类,类似于上面我们自己写的Smarty模板引擎类。plugins是插件的意思,表示里面存放这一系列的插件,我们可以在里面扩展自己的插件。sysplugins是系统核心的插件文件。它里面有assign啊,for啊,foreach啊,if啊等等这些,assign是不是前面自己写的设置属性信息?有了这些的支持,我们才可以在模板中使用。
4.2. 使用Smarty
使用Smarty得把本身主要的类文件和它相关辅助的文件都得复制到我们的工作目录,复制libs文件夹就可以了。好接下来,我们新建一个index.php。程序员开始工作了。首先,新建好index.php文件,与libs文件夹平级,接下来就打开新建好的index.php文件,引入模板引擎类了,模板引擎类就在libs文件夹里。如下:
<?php
//引入官方的模板引擎类
include "./libs/Smarty.class.php";
引入来之后,就是对类进行实例化,调用方法:
<?php
//引入官方的模板引擎类
include "./libs/Smarty.class.php";
//实例化对象
$smarty = new Smarty;
//展示模板,调用display,是不是跟上面写迷你版的smarty是一样的。
$smarty->display('index.html');
好,接下来,就是又美工人员开始写index.html文件了,在写自定义的Smarty,我们把html文件放在一个叫做view的文件夹,混编文件放在一个叫做view_c的文件夹,那么官方的Smarty是不是这样呢?这就要打开官方的Smarty类了,因为我们知道,在写迷你版的时候,定义文件名是不是在自己写的类定义的。所以,打开,ctrl+F查找templates或者templates_c。
所以,我们要创建一个文件夹,名叫templates,存放模板文件,一个叫templates_c,存放混编文件。最终的效果如下:
当然了,上面的libs文件夹你可以改名为smarty文件夹,就是把libs改名为smarty。
简单的测试Smarty
好,我们在index.html的body中写上一段代码:<h2>哈哈哈哈哈</h2>
,那么,当我们运行index.php文件的时候,能不能把官方给我们的效果展示出来?
这样是不是成功啦!!,我们还需要自己写模板引擎类吗,是不是不需要了,别人已经写好了,我们拿来用就行,我们程序员就只需要关注与我们的业务逻辑。
然后它是不是给我们生成了一个混编文件呢?
确实生成了。
传参测试
index.php:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty->assign("name","小霆");
$smarty->assign("addr","广州市白云区");
$smarty->display('index.html');
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
姓名: {$name}<br/>
地址: {$addr}<br/>
</body>
</html>
效果如下:
很明显,传参也是对的,并且可看出Smarty也是用花括号。可以打开官方的模板引擎类,如下图:
属性$left_delimiter是可以修改的,也就是这个类里面的所以都可以修改,但是不推荐,核心类的东西最好不要修改。
5. 保留变量使用
在上面我们用assign方法来传递变量信息,这只是其中的一种方式,总有三种,接下来来讲另外两种。这节讲其中一种,还有一种在第6节。
对PHP里边的超级全局数组变量信息的使用,例如$_GET…常量…等等这些。有这么一个请求:XXX/index.php?sex=男。我们发现他是get请求,get的请求,我们是不是要在index.html用$_GET来接收?我们说过了,模板文件是不允许出现php代码的,只允许出现模板标记花括号,所以,直接写php代码是不行的。还有一个方法,就是在index.php获取到sex的值以assign的值赋值给一个变量。比如:
$smarty->assign("sex",$_GET['sex']);
这种虽然可以,但是不行,它还要赋值给一个变量,我们直接用不行吗?
这时候就用到Smarty的保留变量了,它就是$smarty,所以,我们在自己起变量名的时候,不能叫做smarty,它是一个关键字,不然冲突了。怎么用,如下:
{$smarty.get.sex} //我通过保留变量来访问get的变量信息,具体访问什么呢?sex
常量也一样,不受作用域的限制,在哪都可以访问,不需要assign,要assign都是那些受作用域限制的变量。如下:
{$smarty.const.HOST} //const表示常量,HOST是自己定义的常量名
常量我们只需要在index.php定义好即可。
相应的,get可以替换成post,session,cookies,request,server…
当然了,还可以表示时间戳,如下:
{$smarty.now} //也就是 time()
还有很多,如下:
{$smarty.config} //获取配置信息
{$smarty.section} //跟循环有关
{$smarty.template} //获得当前模板的名称,如果你的模板名是index.html,那获得的就是index.html
{$smarty.current_dir} //返回当前模板的目录名称,也就是templates
{$smarty.version} //模板引擎的版本
{$smarty.ldelim} //获取模板引擎的左定界符 {
{$smarty.rdelim} //获取模板引擎的右定界符 }
6. 配置变量信息
网站上有一些比较简单的变量信息,美工人员可以自行定义并调用,这样可以脱离程序员的依赖,工作比较有主动权。比如美工人员定义了一个变量,你php文件中并没有去assign这个变量,是不是模板中的变量就得不到解析呢?当然,它适用于一些简单的信息。
配置变量是不需要PHP程序来提供的。
6.1. 测试
-
首先,配置信息对应的配置文件要创建好。
所以,我们要建立一个文件夹叫做configs,里面存放配置信息。configs文件夹与libs文件夹平级。然后在configs文件夹下创建一个配置文件,名字随便,比如叫size.conf,后缀是.conf,conf就表示配置的意思。
-
打开创建好的size.conf文件,编辑,如下:。
NETWORK=互联网出版许可证粤002号 POLICE=京公网安备 11000002000088号
-
在模板里面使用上面的两个配置变量,格式:{#变量名称#},那么在index.html中:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {#NETWORK#}<br> {#POLICE#} </body> </html>
-
引入size.conf,如下图:
{config_load file="site.conf"}<!-- 不需要用路径来表示 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {#NETWORK#}<br> {#POLICE#} </body> </html>
最终测试,是不是引入成功了!!!如下图:
还有一点,像上面,我们可以用保留变量来使用,记不记得{$smarty.config},没错,如下代码:{#NETWORK#} {$smarty.config.NETWORK}
上面两个的效果是一样的。
6.2. 数字型的配置信息
当我们在size.conf里面增加这么一句信息,如下:
MONEY=123343242424324324
执行效果如下:
是不是发现了不一样啊,根本跟我们在配置文件配置的不一样,这是为什么呢?上面浏览器展示的数字其实是PHP所能表示的整形的最大数字。不信,用下面代码测试一下,看看是不是一样的。
echo PHP_INT_MAX;
答案就是一样的。我们在配置文件中定义的数字是不是被它们看出数字了,我们定义的数字已经超出PHP所能表示的最大数字。如果我们想表示它,就得加上一对引号,表示它是字符串。
MONEY="123343242424324324"
6.3. 对于{}使用与css或js内容有冲突的解决
-
把smarty的标记{}更改为其他的标记。
-
给{}标记的开始和结束添加空格。
-
如果不想加空格,可以这样,如下代码:
{literal} <style type="text/css"> div{color:yellow;width:500px;height:400px;background-color:lightblue;} </style> {/literal}
也就是说,被{literal}包含的标记是不会被smarty解析的。这样的可读性更好。
6.4. 覆盖问题,设置段
site.conf:
CLR=red
WD=300px
HT=200px
BG=pink
CLR=blue
WD=400px
HT=300px
BG=lightblue
index.html:
{config_load file="site.conf"}<!-- 不需要用路径来表示 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
div{ color:{#CLR#};width:{#WD#};height:{#HT#};background-color:{#BG#}; }
</style>
</head>
<body>
<div></div>
</body>
</html>
最终的效果是不是我们在配置文件中最后一次定义的效果,比如上面CLR,blue是不是把red给覆盖掉了,有这么一个需求,就是可以根据自己的喜好随意切换颜色,就是切换模式,像上面配置文件就有两个模式了,哪要怎么样才能体现两个模式呢?如下:
[year]
CLR=red
WD=300px
HT=200px
BG=pink
[yuandan]
CLR=blue
WD=400px
HT=300px
BG=lightblue
是不是把上面分成了两个段啊。比如我喜欢year段的,哪就要在index.html进行设置,如下:
{config_load file="site.conf" section="year"}
没错,就是section="year"
。这样就ok啦。
注意:如果把section给去掉了,哪它什么都不会给你显示。你设置段,就得使用段。
7. 数组元素访问及foreach遍历
7.1. 数组元素访问
格式如下:
//smarty对数组元素的访问
{$数组[下标]}
{$数组.下标}
不管是索引数组还是关联数组都可以通过上面两种方式访问。
对index.php进行编辑:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty->assign('fruit',array('banana','apple','orange','watermelon'));
$smarty->display('index.html');
再对index.html进行编辑:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{$fruit[2]} <!--orange-->
{$fruit.3} {*watermelon*} <!--这种格式{* *}属于注释 -->
</body>
</html>
7.2. 遍历数组
foreach
格式如下:
{foreach 数组 as $k=>$v} 或 {foreach 数组 as $v}
做具体数组遍历
{foreachelse}
数组没有任何元素信息
{/foreach}
跟php的基础语法中的foreach的区别在于foreach后面是括号括起来的。这里可以省略。if也是一样的道理。
那么index.html如下:
{foreach $fruit as $k => $v}
{$k}--{$v}<br/>
{foreachelse}
数组没有任何元素
{/foreach}
关联数组也是如此,但是如果遍历的关联数组前面要有序号怎么办?
值变量@iteration-->从1开始的序号信息
值变量@index-->从0开始的序号信息
那么代码如下:
{foreach $fruit as $k => $v}
{$v@iteration}--{$k}--{$v}<br/>
{foreachelse}
数组没有任何元素
{/foreach}
最终效果:
1--0--banana
2--1--apple
3--2--orange
4--3--watermelon
除了表示序号的,还有:
值变量@first-->判断第一个元素,返回boolean
值变量@last-->判断最后第一个元素,返回boolean
值变量@total-->获得数组元素长度,可以放在foreach外面
值变量@show-->判断当前数组是否有元素遍历出来,返回boolean,比如像空数组,就算遍历也没有元素出来,就是false,false就是0。
section
section遍历只能遍历索引数组,不能遍历关联数组。
格式如下:
{section name=名称 loop=被遍历的数组}
{$数组[名称]} 获得被遍历出来元素的值
关键字使用:
{$smarty.section.名称.iteration}
{$smarty.section.名称.index}
{$smarty.section.名称.first}
{$smarty.section.名称.last}
{/section}
index.html如下:
{section name=v loop=$fruit}
{$fruit[v]}
{/section}
8. 分支结构语句
单路分支
{if 条件}
分支逻辑
{/if}
双路分支
{if 条件}
{else}
{/if}
多路分支
{if 条件}
{elseif 条件}
{elseif 条件}
{else}
{/if}
9. 自定义函数
9.1. 模板自定义函数(了解即可)
所谓模板自定义函数:是smarty模板提供给你的函数。格式: {函数名 属性名=属性值}
-
assign:assign上面已经提到过,我们都不默生,它是模板引擎类当中的一个函数,assign它的作用就是用于在模板被执行时为模板变量赋值。我们在模板文件中index.html或者后缀是.tpl都没错,因为它是模板,我们在模板里有这么一句话:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {assign} {*报错*} </body> </html>
上面直接执行index.php是报错的,为什么会报错,因为它缺少两个属性,如下:
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {assign var=name value=Lee} </body> </html>
上面var表示一个变量,value表示变量的值,这样虽然不会报错,就是没效果,其实在模板中这样写,就相当于我们在index.php中这样写:
$smarty->assign("name","Lee");
所以知道模板页面该怎么把变量输出出来了吧,如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {assign var=name value=Lee} {*值加上双引号和不加双引号都可以*} {$name} </body> </html>
这样就正确显示。
-
counter:用于输出一个计数的过程 ,如图:
{counter} {counter} {counter start=7} {*表示往后都是从7开始*} {counter} {counter} {counter}
最终结果是1 2 7 8 9 10
{counter start=3 skip=2} {*表示往后都是从3开始,步长为2*} {counter} {counter} {counter} {counter} {counter}
最终结果是3 5 7 9 11 13
{counter start=3 skip=2 direction=down} {*表示往后都是从3开始,步长为2,down表示递减,up就是递增*} {counter} {counter} {counter} {counter} {counter}
最终结果是3 1 -1 -3 -5 -7
{counter start=3 skip=2 direction=down} {counter} {counter print=false} {*不输出*} {counter} {counter} {counter}
最终结果是3 1 -3 -5 -7
{counter assign=c} {*输出值将被赋给模板变量的名称*} {$c}
-
cycle:用于交替轮换一组数据,比如背景色轮替交换。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p style="background:{cycle values='red,green'};">1</p> <p style="background:{cycle values='red,green'};">2</p> <p style="background:{cycle values='red,green'};">3</p> <p style="background:{cycle values='red,green'};">4</p> <p style="background:{cycle values='red,green'};">5</p> {*上面的操作要放在.tpl后缀的文件上,如果放在.html文件,上述语句会编译报错*} </body> </html>
效果如下:/font>
-
debug
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {debug} </body> </html>
-
eval:eval可以显示普通变量和配置变量。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {eval var=$name} {*输出变量$name,跟{$name}是一样的*} {eval var=#NETWORK#} {*输出配置变量,跟{#NETWORK#}是一样的*} </body> </html>
跟assign结合:
{eval var=#NETWORK# assign=c} {$c} {*或者{eval var=$c}*}
-
fetch:fetch可以引入其他文件的源代码。
{fetch file="http://www.baidu.com"}
说到fetch,要知道它跟display的区别,如下代码:
$smarty->display(index.tpl);
就相当于:
$html=$smarty->fetch(index.tpl); echo $html;
fetch仅是计算出应输出的结果,但是不输出,只把结果返回。
-
html_image:
{html_image file="xxx" href="xxx" border="xxx"}
-
html_table:显示表格
index.php$smarty->assign("table",array(1,2,3,4,5,6));
index.tpl
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {html_table loop=$table } </body> </html>
-
math:用于计算
index.php$smarty->assign("x",3); $smarty->assign("y",19);
index.tpl
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {math equation="$x+$y"} {*或者可以这么写{math equation=x+y x=$x y=$y}*} <br> {$x+$y} {*这也一样可以,跟上面比多此一举*} </body> </html>
-
mailto:发送邮件。
{mailto address="xxx.qq.com" text="小霆"}
-
html_checkboxes: 请看第11章节。
-
html_select_date:可以显示日期的下拉列表。
{html_select_date month_format='%m'} {*月份默认是英文的,所以要格式化*}
年份不对,不能选择,这么才能让它选择呢?如下代码:{html_select_date month_format='%m' start_year="1999" end_year="2060"}
然后怎么把年放到前面去呢?
{html_select_date month_format='%m' start_year="1999" end_year="2060" field_order="YMD"}
注意观察field_order,默认是MDY,YMD就是年月日。
9.2. PHP自定义函数
函数注册—单标签 类似html的<br> br标签不是闭合标签
就是你在php文件里自己创建了一个函数,然后通过smarty的函数注册功能将你的函数注册到模板中去,而模板直接写上函数名,和它的属性,就可以调用这个函数。
假如在模板中有这么一句话:
{info age=28 height=178 blood=A}
也就是说,有个函数叫info,这是smarty没有的函数,那我们要在index.php哪里进行创建。
在模板里注册一个函数,并且可以传参,可以使用register_function(‘模板函数名’,‘函数名’)
//这是一个自定义函数
function fn_info(){
return "你好";
}
$smarty->registerPlugin('function','info','fn_info'); //将自定义函数注册到smarty里面去
//第一个参数是你要注册的类型,你要注册的类型就是function,这也是跟传统的register_function方法的区别,
//注意:register_function以被淘汰。
接下来测试一下:执行index.php,就是你好,说明成功。现在是接收数据,有3个数据,用数组形式。
function fn_info($a){
print_r ($a); //Array ( [age] => 28 [height] => 178 [blood] => A )
return "你的年龄是:{$a['age']}岁,身高:{$a['height']},血型:{$a['blood']}";
}
块注册—双标签(闭合标签)
我们上面的例子{info}是不是一个单标签,如果是{info}内容{/info},那么就是双标签,那要怎么实现呢?注意了这时候注册的不是函数,而是块。
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{info age=28 height=178 blood=A}
ssss
{/info}
</body>
</html>
index.php:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
function fn_info($a){
return "你的年龄是:{$a['age']}岁,身高:{$a['height']},血型:{$a['blood']}";
}
$smarty->registerPlugin('block','info','fn_info');
$smarty->display('index.html');
注意第一个参数是block,是块的意思,区别于上面的function。
看结果:
可是为什么ssss并没有输出出来呢?这就是自定义函数的第二个参数了,如下:
function fn_info($a,$b){
echo $b; //输出ssss
return "你的年龄是:{$a['age']}岁,身高:{$a['height']},血型:{$a['blood']}";
}
注意$b,$b就是表示内容ssss。
9.3. 按插件形式扩展的自定义函数
就是在libs文件夹下的plugins文件夹下新建一个文件,那这个文件就是我们自定义的插件。
- 如果是函数插件,文件必须放在插件目录(plugins),文件名必须是function.xxx.php,里面的函数名必须是smarty_function_xxx($params,&$smarty)。
- 如果是块插件,文件必须放在插件目录(plugins),文件名必须是block.xxx.php,里面的函数名必须是smarty_block_xxx($params,$content,&$smarty)。
所以:
这时候我们php就剩下这些了:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty->display('index.html');
index.html页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{info age=28 height=178 blood=A}
</body>
</html>
效果一样可以出来。
10. 内置函数
什么是内置函数,内置函数是模板引擎的一部分,用于实现模板中一些流程控制等结构的语句。内置函数和自定义函数的区别是:内置函数不能修改,也不能创建和内置函数同名的自定义函数。
-
{php}内容{/php}表示可以在模板中使用php代码。但这违背了业务和模板分离的原则,所以不推荐使用。
-
{include file=‘xxx.tpl’} 引入tpl模板文件
-
{config_load file=“xxx”}
-
{literal}xxx{/literal}
-
{if}…{elseif}…{else}…{/if}
-
{strip}…{/strip} 将代码中的空格压缩掉
-
{ldelim}…{rdelim} 左分隔符
{
和右分隔符}
-
{capture}…{/capture} 将包含的数据保存起来,指定输出
{capture} 我失踪了~~ {/capture}
这样是看不到效果的。要想看到效果,如下:
{capture name="me"} 我失踪了~~ {/capture} {$smarty.capture.me}
-
{insert} 和自定义函数类型,但有不被缓存的特点。
index.php:function insert_bbb(){ return 124; }
{insert} 和自定义函数类型,但有不被缓存的特点。
index.html:{insert name="bbb"} //输出124。如果name等于aaa,那么方法名就是insert_aaa
-
{foreach} 如下代码:
index.php$smarty->assign("arr1",array(1,2,3,4,5));
index.html
{foreach from=$arr1 item=value key=a} {$a}:{$value} {foreachelse} 没有任何数据 {/foreach}
可以给它一个名字name:
{foreach from=$arr1 item=value key=a name=abc} {$smarty.foreach.abc.iteration}:{$a}:{$value} {foreachelse} 没有任何数据 {/foreach} {$smarty.foreach.abc.total} {*total表示有多少条数据*}
11. smarty表示复选框,下拉列表,单选按钮的使用
复选框
index.php如下:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty->assign("outval",array("a"=>'乒乓球',"b"=>'篮球',"c"=>'橄榄球',"d"=>'足球'));
$smarty->display('index.html');
index.html如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>复选框应用</h2>
爱好:
<!-- <input type="checkbox" name="hobby[]" value="a">乒乓球<br>
<input type="checkbox" name="hobby[]" value="b">篮球<br>
<input type="checkbox" name="hobby[]" value="c">橄榄球<br>
<input type="checkbox" name="hobby[]" value="d">足球-->
{html_checkboxes name="hobby" options=$outval}
</body>
</html>
注意看smarty提供的html_checkboxes,它当中的options表示多选框的值-显示的数组。它集合了values和output,output就是显示外面的数据,就是浏览器看到的数据。你也可以单独使用values和output,是数组类型。
最终效果:
如果想让它一上来就自动选择某个值:
在index.php中
$smarty->assign("seled","c"); //也可以是数组,让它多个选择
在index.html中
{html_checkboxes name="hobby" options=$outval selected=$seled}
还有分割符号:
{html_checkboxes name="hobby" options=$outval separator="<br/>"}
用换行来分割。
还有给<label>和<input>设置ID属性:
下拉列表
index.php:
$smarty->assign("area",array(1=>'广州',2=>'揭阳',3=>'深圳',4=>'上海'));
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>下拉列表应用</h2>
城市:
<!-- <select name="city">
<option value="1">广州</option>
<option value="2">揭阳</option>
<option value="3">深圳</option>
<option value="4">上海</option>
</select>-->
{html_options name="city" options=$area}
</body>
</html>
如果一上来就让某个选中,跟上面讲复选框是一样的。当然了,我们的下拉框是不是可以多项选中,如果要多项选中,则:
{html_options name="city" options=$area selected=$seled multiple="multiple"} //这时候$seled应该是数组
单选按钮
单选按钮就是{html_radios},操作跟上面是一样的,什么name啊,options啊,selected啊,分隔符啊,都是一样的。
12. 已有模板(纯html)与Smarty结合
纯html所要用到的静态资源,比如css,js,img都要放到一个目录里,改目录起名为public,在public目录下有3个目录,分别是存放css文件的目录,一个存放js文件的目录,还有一个存放img的目录。
注意html引入静态资源时的路径要以入口文件,入口文件应该是php,因为是由php来调用html的,通过上面的学习可知。所以路径的引入要以php,也就是入口文件为基准。但如果css文件本身有引入img图片,其路径相对css文件设置。
完了之后,接下来就是利用上面所学的知识,在入口php文件获得变量信息用于模板显示。
13. 布局继承使用
在一个网站中多个页面他们头部可以是一样的,底部也可能是一样的,那怎么多一样的维护起来也不是很方便,我们应该只维护一份,在这一份当中如果有个字变了,那么其它多个页面都会改变,这就要用到布局继承的知识了。
为了使得许多页面的共同头部,脚部开发/维护方便,我们制作一个布局页面,其它具体业务页面来填充该"布局"页面。
在templates文件夹下创建一个layout.html页面,它是一个布局页面,如下:
<meta charset="UTF-8">
<div style="width: 100%;height: 100px;background-color: antiquewhite">头部</div>
{block name="main"}{/block} <!--占位符,这里是具体的业务逻辑,main是随便起的,因为占位符可以有多个-->
<div style="width: 100%;height: 100px;background-color: red">底部</div>
然后新建两个页面,一个是index.html,一个是登陆页面login.html,在这两个页面当中都有相同的头部和底部,只是中间的业务逻辑不同罢了,而头部和底部我们是不是在layout.html中就已经定义好了,所以,在这两个页面,我们只需要写中间部分的业务逻辑即可,头部那些用一个标签引进来即可。所以:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{extends file="layout.html"} <!--引入layout.html-->
{block name="main"}<div>index.html</div> <!--layout.html当中占位符可以有多个,所以要指定name,最后要闭合-->
<div>index.html</div>
<div>index.html</div>
<div>index.html</div>
<div>index.html</div>
<div>index.html</div>
<div>index.html</div>{/block}
</body>
</html>
index.php就不用说了,执行index.php,效果展示如下:
同理,login.html也是如此,如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{extends file="layout.html"}
{block name="main"}
<div>登录页面</div>
{/block}
</body>
</html>
效果展示:
14. 布局继承扩展使用
上面是按照上中下布局的,现在如果上中下不变,但是中间部分还得再分,什么意思,如下两副图:
上面两幅图就是两个页面,两个html,头部和底部不说,中间部分左边的目录其实是不变的,只是目录的右边在随着左边的目录变化,那么左边目录是不是也可以抽取出来,放在布局页里。
像这种来布局上中下的布局就不合适了,最好设计为上左右下布局。
当然,你来继承的时候,不仅仅是上左右下的布局,也可以是上中下的布局。就是说,万一某个页面它中间部分没有左边的列表信息呢。如下图:
新建layout.html布局页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
#head{ width:730px;height:90px;background-color:lightblue; }
#main{ width:730px;height:300px;background-color:pink; }
#foot{ width:730px;height:90px;background-color:lightblue; }
#left{ width:230px;height:300px;background-color:lightgreen;float:left; }
#right{ width:450px;height:300px;background-color:lightgray; float:right; }
</style>
</head>
<body>
<div id="head">首页,媒体,导航,输入,网页模板,其它</div>
<div id="main">
{block name="center"}
<div id="left">
欢迎页<br/>
我的订单<br/>
收货地址<br/>
更改密码<br/>
黑名单管理<br/>
</div>
<div id="right">
{block name="right"}{/block}
</div>
{/block}
</div>
<div id="foot">订购方式,联系我们,售后保障</div>
</body>
</html>
注意:
- 布局页面可以有许多block,子级页面也可以有许多block,它们通过name属性进行关联。
- 子级页面除了extends和block其他内容不给显示。
- 布局页面的block可以有默认内容,子级页面不实现就直接显示,实现就覆盖。
- 布局页面的block可以彼此嵌套,子级实现可以有针对性实现。
- {$smarty.block.child}布局可以调用子级的内容。
- {$smarty.block.parent}子级页面可以调用父级页面的内容。这样子级虽然实现了父级的内容,但是我们可以通过此代码把父级的默认内容拿过来。
新建一个注册页面register.html:
注册页面是一个典型的上中下的效果,它中间部分没有左边的信息栏,即使这样,它一样可以继承上左右下的布局页:
{extends file="layout.html"}
{block name="center"}<div>注册页面</div>{/block}
{*实现了布局页面的center,是不是把里面的默认内容给覆盖掉了啊*}
效果如下:
好,接下来是实现上左右下的效果,我们在上面布局页面的代码中,有一个我的订单,那么我们就新建一个订单页面myorder.html:
{extends file="layout.html"}
{block name="right"}<div>订单页面</div>{/block}
{*订单页面就得实现right了,这样才有左边的信息栏*}
效果如下:
在templates文件夹中为了避免模板页面和布局页面混乱,会专门给布局页面创一个文件夹,就在templates里创,叫common。
15. 变量(修饰)调节器的使用
在模板中获得的变量信息,有可能不是我们需要的信息(例如时间戳,不好读,需要将其转换为格式化信息),需要调用其它函数对该信息进行第二次,第三次等修饰才会变成我们想要的结果,smarty本身不支持我们在模板中使用php函数,其把函数封装了一下,封装的函数就是smarty的变量调节器。
比如date_format就是变量调节器,它是对php函数date的封装,
在学习php基本语法时,是不是date("Y-m-d:i:s",时间戳);
再比如upper也是变量调节器,upper是不是转换为大写,首先格式是{变量|变量调节器}
所以{$title|upper}的意思就是把$title所输出的东西转换为大写,upper就是对strtoupper()函数的封装。
然后上面格式化就是:{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
总结一下格式,就是:
{变量名称|修饰变量的方法名:参数:…}
变量和修饰变量的之间用"|“隔开。如果有多个参数,则使用”:"隔开。
官方文档:https://www.smarty.net/docs/zh_CN/language.modifiers.tpl
date_format支持格式:
%a - 当前区域星期几的简写
%A - 当前区域星期几的全称
%b - 当前区域月份的简写
%B - 当前区域月份的全称
%c - 当前区域首选的日期时间表达
%C - 世纪值(年份除以 100 后取整,范围从 00 到 99)
%d - 月份中的第几天,十进制数字(范围从 01 到 31)
%D - 和 %m/%d/%y 一样
%e - 月份中的第几天,十进制数字,一位的数字前会加上一个空格(范围从 ’ 1’ 到 ‘31’)
%g - 和 %G 一样,但是没有世纪
%G - 4 位数的年份
%h - 和 %b 一样
%H - 24 小时制的十进制小时数(范围从 00 到 23)
%I - 12 小时制的十进制小时数(范围从 00 到 12)
%j - 年份中的第几天,十进制数(范围从 001 到 366)
%k - 小时,24 小时格式,没有前导零
%l - 小时,12 小时格式,没有前导零
%m - 十进制月份(范围从 01 到 12)
%M - 十进制分钟数
%n - 换行符
%p - 根据给定的时间值为 am' 或
pm’,或者当前区域设置中的相应字符串
%r - 用 a.m. 和 p.m. 符号的时间
%R - 24 小时符号的时间
%S - 十进制秒数
%t - 制表符
%T - 当前时间,和 %H:%M:%S 一样
%u - 星期几的十进制数表达 [1,7],1 表示星期一
%U - 本年的第几周,从第一周的第一个星期天作为第一天开始
%V - 本年第几周的 ISO 8601:1988 格式,范围从 01 到 53,第 1 周是本年第一个至少还有 4 天的星期,星期一作为每周的第一天。(用 %G 或者 %g 作为指定时间戳相应周数的年份组成。)
%w - 星期中的第几天,星期天为 0
%W - 本年的第几周数,从第一周的第一个星期一作为第一天开始
%x - 当前区域首选的时间表示法,不包括时间
%X - 当前区域首选的时间表示法,不包括日期
%y - 没有世纪数的十进制年份(范围从 00 到 99)
%Y - 包括世纪数的十进制年份
%Z - 时区名或缩写
%% - 文字上的 `%’ 字符
再讲一个default,默认值,就是如果模板有一个变量是未定义的,就可以使用default,不然就会报这个变量未定义。
{$aa|default:"bb"}
还有一个,如下:
//在index.php中
$smarty->assign('baidu',"<a>百度一下</a>");
如果你是这样{$baidu}获取,只能获取百度一下这四个字,如下:
但是如果你用一个变量调节器修饰一下,就是escape
{$baidu|escape} {*转义,转换html标签为符号实体*}
效果如下:
缩进符号indent,直接看代码:
{$baidu|indent:4:"hello"} {*表示来个4个缩进,每个缩进都是hello*}
效果如下:
还有替换replace:
{$baidu|replace:"百度":"百"} {*结果是百一下*}
还有去除html标签的strip_tags。截取的truncate:
{$talk|truncate:20} {*截取20个字符,一个英文一个字符*}
变量调节器可以有多个,嵌套一起使用,多个用|分隔即可。
上面只是笼统的说一下,详细还得去看官方文档。
16. 缓存
16.1. 缓存介绍
缓存类型有两种:页面缓存和数据缓存。
页面缓存:php代码被php模块解释完毕生成的静态内容,放到一个文件里边,该文件称为缓存文件。
数据缓存:把mysql的数据读取出来放到速度更快的介质上(内存)操作。
smarty调用display方法获得模板内容,首先:判断是否有静态缓存文件,如果有直接获取并返回给用户,其次:没有静态缓存文件,判断是否已经存在对应混编文件,如果有直接走,如果没有对应的混编文件,则按部就班,每一个过程都会执行。
16.2. 缓存设置及更新
开启缓存
编辑index.php
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty->assign('animal',array('dog','cat','tiger'));
$smarty->display('index.html');
编辑index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>缓存制作</h2>
<ul>
{foreach $animal as $k => $v}
<li>{$v}</li>
{/foreach}
</ul>
</body>
</html>
下一次访问就是直接拿混编文件了,并不会被模板引擎进行替换操作,性能更高,但是,我们还可以把混编文件存变成一个纯html的页面缓存起来,下次就直接拿缓存好的html页面,性能更高,不然,你直接拿混编文件,因为混编文件里面有php代码,所以要给php进行解析,在返回个浏览器,是不是经历了一个给php解析的操作,如果我们把php解析好的,最终给浏览器的页面缓存起来,那么性能上是不是就更优了,那这要怎么做?
想设置缓存,就在php页面里对$smarty对象进行操作,如下:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
//开启缓存,caching是$smarty对象的属性,等于1表示true,真,表示缓存已开启
//注意,开启的是页面缓存
$smarty -> caching = 1;
$smarty->assign('animal',array('dog','cat','tiger'));
$smarty->display('index.html');
效果如下:
开启缓存之后是不是会在项目下新建一个文件夹,叫cache,里面就是纯html代码,浏览器可以直接解析,不需要php解析,比起混编文件夹性能更加提高。注意,它是页面缓存。这时候你再访问,它就是直接拿缓存文件了。
因为你现在是直接拿缓存文件了,那如果你在index.php中assign一些新数据,修改了一些内容,那么你再去访问缓存文件就不合适了,就要让缓存文件实时更新,这又怎么办?
缓存更新
-
删除对应的缓存文件,系统会更新,这当然毋庸置疑。
-
对应的模板文件(包括对应的配置文件,布局文件,包含文件)有更新,缓存会自动更新。注意,如果对应的模板文件有更新,缓存介绍那幅图,就会走中间的那条路,也就是说他会经过模板引擎和PHP模块。
-
缓存文件的有效时间过期,会自动更新。默认的时间是3600秒。
<?php include "./libs/Smarty.class.php"; $smarty = new Smarty; //开启缓存,caching是$smarty对象的属性,等于1表示true,真,表示缓存已开启 //注意,开启的是页面缓存 $smarty -> caching = 1; //修改缓存文件的有效时间 $smarty -> cache_lifetime = 20; //20秒 $smarty->assign('animal',array('dog','cat','tiger')); $smarty->display('index.html');
上图我给它设置的是20秒,20秒过后将自动更新。注意,它是重新生成,把原来的给覆盖掉。
display方法执行时:
4. 判断缓存是否开启
5. 判断模板文件是否有更新(如果有更新,3,4都省略)
6. 判断缓存文件是否存在(缓存文件时间是否过期)
7. 判断混编文件是否存在
8. 展示模板内容
9. 缓存开启,生成缓存文件
单模板多缓存制作
一个模板生成多个缓存文件。
index.php页面:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty -> caching = 1; //开启缓存
$smarty->display('index.html');
index.html页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>单模板多缓存</h2>
显示商品信息<br/>
第{$smarty.get.page}页数据<br>
</body>
</html>
在地址栏上xxx?page=4,那么结果就是:
当你第二次在地址栏上xxx?page=1,那么结果还是4,page等于2,结果还是4,因为你开启了缓存,所以在第一次访问时就已经缓存,第二次,第三次…都是第一次的结果,哪怎么办?解决办法如下:
//diaplay(模板,标志);
//会根据不同标志生成该模板的不同缓存文件
$smarty->display('index1.html',$_GET['page']);
这样,如果page等于1,哪就是第1页,page等于2,结果就是第二页,一个模板生成多个缓存。
局部不缓存
缓存页面可以把全部页面数据都给缓存起来,其中有些数据不适合缓存,例如:天气信息,用户信息等等,这样就需要设置"局部不缓存"。
- {$title nocache} 单个变量不缓存
- $smarty->assign(名称,值,true); 单个变量不缓存
- {nocache}内部内容都不缓存{/nocache}
缓存集合使用
缓存集合 是单模板多缓存的升级用户,一个模板可以变着花样的生成许多缓存文件。
以上筛选商品的五种条件,做“数学的排列组合”,每种情况都生成一个缓存文件。
index.php:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty -> caching = 1;
$smarty->display('index1.html');
index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- ?brand=apple&price=2002&network=cmcc&big=2 -->
<h2>缓存集合</h2>
商品展示<br/>
条件:
品牌:{$smarty.get.brand}<br/>
价格:{$smarty.get.price}<br/>
网络:{$smarty.get.network}<br/>
屏幕大小:{$smarty.get.big}<br/>
</body>
</html>
解决办法:
<?php
include "./libs/Smarty.class.php";
$smarty = new Smarty;
$smarty -> caching = 1;
$brand = $_GET['brand'];
$price = $_GET['price'];
$network = $_GET['network'];
$big = $_GET['big'];
//diaplay(模板,mark1|mark2|mark3|mark4); “/”也可以
//对各种mark做排列组合,每种情况都生成缓存文件
$smarty->display('index1.html',$brand."|".$price."|".$network."|".$big);
说白了,就是用户的每一次筛选都会生成一个缓存文件,但前提是缓存文件已经有了,就是筛选条件跟你的筛选条件一样,如果没有一个缓存文件的筛选条件跟你的筛选条件一样,就生成一个新的缓存文件,不知道你们懂不懂我的意思。
$smarty->force_cache=true;
上面的代码表示强制重新生成缓存文件,也就是说,旧的缓存文件它就不走了。
删除缓存:clearCache(模板名称) 删除改模板生成的所有缓存文件。clerCache(模板,标志) 删除指定模板,指定标志开始的全部缓存文件。clearAllCache() 删除全部缓存文件。clearCache(null,标志),我不管哪个模板,只有是以这个标志开始的缓存文件,我都删除。
比如一个缓存文件apple^2002^cmcc^2^13260ad4c0d4fc592b81d3a3acaac4c453655788.index1.html.php
我想删除这个缓存文件,这么删:
$smarty -> clearCache("index.html","apple|2002|cmcc|2");