模板引擎作用(优点):可以让美工和程序员分开;可以为同一段PHP程序开发出多套模板;可以生成多个目标。
(美工修改模板不影响php业务逻辑代码;程序员对php业务逻辑代码的修改也不影响美工的工作)
1、为了避免在每个php文件里都重复写加载Smarty类的代码,所以新建一个init.inc.php文件,这样在其它php
文件里只需包含此文件即可,代码如下:
<?php
//echo str_replace("\\",'/',dirname(__FILE__)).'/';
define("ROOT",str_replace("\\",'/',dirname(__FILE__)).'/');
require(ROOT."libs/Smarty.class.php");//引入Smarty类
$smarty = new Smarty();
$smarty->setTemplateDir(ROOT.'tpls')//设置模板路径
->setCompileDir(ROOT.'coms')//设置编译后的文件存放路径
->setConfigDir(ROOT.'configs');//设置配置文件目录
$smarty->setLeftDelimiter('<{');//设置左右定界符
$smarty->setRightDelimiter('}>');
$smarty->setAutoLiteral(false);//设置定界符之间允许空格(默认为true即不允许有空格)
注释:<{* 注释的内容 *}>
2、因为模板文件最后是通过模板引擎smarty加载到php程序中执行的,所以在模板里面设置的路径都得相对于
此php程序所在的路径,而不是相对于模板的路径,否则将找不到该路径下的图片资源等。同理,
<link href="layout.css">和<script src="js/jquery.js"></script>指定的路径也要相对于php程序来定。
3、编译目录中存储php文件执行后生成的缓存文件,除非模板发生了改变,否则不会重新生成,而是直接读取
此缓存文件,这样一定程度就减少了重复读取数据库的操作。
4、向模板分配变量并显示模板:
$smarty->assign('key','value');
$smarty->assign(array('key'=>'value','key1'=>'value1'));//一次性分配多个变量
$smarty->display('demo.html');
5、smarty中在双引号中写变量或函数
如:$var="aaa"; "111 $var 111"=>"111 aaa 111"(有空格)
或 $var="aaa"; "111`$var`111"=>"111aaa111" (无空格)
"111<{date="y-m-d H:i:s"}>111"
6、访问数组变量尽量使用“.”语法,数字为下标则使用中括号[]访问。
如:$arr = array("233","tel"=>"12345678")
访问:$arr[0]="233". $arr.tel="12345678".
7、注册函数成标签
$smarty->registerPlugin("function","myfun","test");//第一个参数指明转换类型,第二个参数是转换后供使用的标签,
第三个参数是要注册的函数名。(将test函数注册成myfun标签)
function test($args){...封装具体的实现逻辑...//$args=array("name"=>"yi","color"=>"red")}.
模板里即可使用:<{myfun name="yi" color="red"}>
8、smarty模板中的自定义函数
分为三类:变量调节器('modifier')、函数('function')、块函数('block')。
有两种做法:
1、使用smarty对象中的registerPlugin()方法将PHP中的函数注册成smarty中的函数。
三个种类插件的用法:
1、变量调节器的用法: <{$var|myfun:"one":"two"}>
2、函数的用法:<{myfun color="red" size="6" num="5"}>(和使用html标记很像)
3、块函数的用法:<{myfun color="red" size="6"}>$content<{/myfun}>
2、开发smarty的插件(以独立的特定文件添加插件)。
一、声明的位置
可以在Smarty类库中原有的plugins目录下创建,也可以使用自己指定的目录
($smarty->addPluginsDir(目录名);//smarty3中的方法)
二、文件的命名
修改器:modifier.修改器名称.php
函数: function.函数名称.php
块函数:block.块函数名称.php
三、函数的命名
修改器:smarty_modifier_修改器名称()
函数: smarty_function_函数名称()
块函数:smarty_block_块函数名称()
四、参数的规则
修改器:smarty_modifier_修改器名称($var,$a="",$b="",$c="")
函数: smarty_function_函数名称($args,$smarty)
块函数:smarty_block_块函数名称($args,$content,$smarty,&repeat)//$repeat在首次调用块函数标签时为真,
此后的所有调用如闭合标签,此变量值都为假,所以为了保证块函数中间内容可以输出且只输出一次,加if(!$repeat)
{return $content;}才输出内容。
9、smarty的变量调解器--变量修改器
作用:
1、从php中分配给模板的变量;
2、需要模板中对变量在输出前进行处理;
3、处理方式就是使用“函数”;
4、在smarty3中可以直接调用php函数;
5、变量在输出之前可以由php程序员在php端处理。
使用场合:
例子1:标题可以直接分配到模板中,在模板中处理截取一个,显示全称一个;
例子2:时间在数据库中都是以时间戳来保存,交给模板,模板中想输出什么格式都可以。
注意:可以直接在模板中使用php函数,但不建议这样使用。
<{$var}>
<{$var|函数名}>
<{$var|函数名:args2:args3:...}>
变量调解器使用的语法:
1、使用“|”后面跟上函数
2、函数的第一个参数就是|前面的变量
3、第二个参数以后的多个参数使用“:”分隔开
变量调解器有哪些可用?
1、在smarty中有一些自带的变量调解器函数
2、自定义一些变量调解器函数
$smarty->registerPlugin("modifier","myfun","test");
第一个参数是类型 modifier是注册修改器;
第二个参数是在模板中使用的修改器名称;
第三个参数是php中自己定义的函数或php系统函数。
注意:如果是系统函数,第一个参数必须是要修改的变量本身。
若系统函数第一个参数不是变量本身,则可以通过加注册函数将其变量改成第一个参数。
组合变量修改器:同一个变量使用多个修改器一起处理。
test(substr($str)) //嵌套使用
<{$var|func1:args2:args3|func2|func3}>
在模板中可以使用多个"|"添加多个变量修改器函数。
10、三种主要的变量
变量和函数是模板中最主要的形式:
一、从php中分配的变量
$smarty->assign();
动态变量需要从php分配给模板使用。
二、从配置文件中读取的变量
Smarty配置文件中的内容,不是php读取,而是就在Smarty模板中直接应用变量。
让用户来修改模板的版式或外观。
1、配置文件需要放置在什么位置,需要设置多少个配置文件,及如何去命名。
$smarty->setConfigDir(目录);
2、配置文件该如何编写?
变量名=变量值(不需要为变量值加双引号(加了也可以),不要加任何空格(可以))
3、如何在模板中找到配置文件?
导入配置文件:<{config_load file="test.conf"}> 或 <{config_load "test.conf"}>
4、如何在模板中读取配置文件中的内容使用呢?
使用配置文件的变量:<{#变量名#}> 或 <{ #变量名# }>(注意#位置是紧贴变量名的)
若是要为不同页面(如首页、二级页或三级页面)分别显示不同内容变量,可以使用边界来区分限制显示。
如在配置文件 test.conf 中:
wholeArea=233(全局可使用)
[一级页面]
one=111
[二级页面]
two=222
[三级页面]
three=333
然后在模板文件中:引入配置文件时加限定:{config_load file="test.conf" section="x级页面"}
(x=一、二、三)即可分别显示一级、二级或三级的页面。
三、保留变量
直接在模板中就存在即可直接使用的变量
$_GET $_POST $_SESSION $_COOKIE $_ENV $_SERVER...
{$smarty.get.name}//访问get参数name(全部转换成小写字母单词如get)
11、自定义一些常用的函数插件用法
12、smarty3 的缓存控制
1、建立缓存
$smarty->caching = true;//开启缓存
$smarty->setCacheDir('dir');//设置缓存目录
2、处理缓存的生命周期
$smarty->cache_lifetime = lifetime;//以秒为单位
3、每个模板可以设置多个缓存
在 display() 上面处理,第二个参数使用一个不同的(唯一)的值,就可以为第一个参数的模板文件保存
一个对应的缓存文件。如:$smarty->display("demo.html",$_SERVER['REQUEST_URI']);
$_SERVER['REQUEST_URI']即为当前运行的文件后部分路径。
4、为缓存实例消除数据库处理的开销
if(!$smarty->isCached('demo.html',$_SERVER['REQUEST_URI'])){页面未缓存则为处理数据库等操作};
5、关闭局部缓存
1、在php端,如果不需要缓存的动态数据分配,要放到isCached()判断之外;
2、在模板中,如果不需要缓存的页面内容,要放到<nocache>...</nocache>标签之间。
6、清除缓存
如 $smarty->clearAllCache();//清除所有缓存
13、Smarty3 的模板继承特性
$smarty3 提供的新特性——模板继承特性
1、如何实现模板之间的继承
是模板之间的事,和php程序没有关系;是在模板中使用<{extends}>函数实现模板继承的。
在模板文件中直接继承自par.html模板:<{extends file="par.html"}> 或 <{extends "par.html"}>。
如果使用<{extends}>函数,必须用在子模板中的第一行(注意)
可以在php中使用Smarty对象中的display()方法代替<{extends}>
在display("extends:模板资源类型");
如:$smarty->display("extends:par.html|child.html|grandChild.html");//grandChild.html继承自
child.html,child.html继承自par.html。
但是smarty3.1.3显示不了,出现({extends file='extends:par.html|child.html|grandChild.html'
extends_resource=true})提示。
2、在子模板中覆盖父模板中的部分内容区域
在父模板中声明一个区域“块”<{block}>,如果在子模板中需要改多个父模板中的位置的内容,就需设置多个
<{block}><{/block}>,也需要为各个块起名字如<{block name="blockName"}><{/block}>
注意:
1、在父模板中定义了<{block}>块后对其显示结果无影响,只是为了在其子模板中能找到区域源并将其内容覆盖。
2、如果子模板继承了父模板,那么它只能包含<{block}><{/block}>标签的内容并覆盖,其它内容都会被模板忽略。
3、合并子模板和父模板的<{block}><{/block}>标签的内容
1、在子模板使用 append 在{block}标签后面添加或 prepend 在{block}标签前面追加内容;
2、使用 Smarty 的保留变量<{$smarty.block.child}>【在父模板中写】作为占位符,将子模板{block}的内容
插入到父模板相应的任何位置;(如:<{block name="writeToPar"}>111<{$smarty.block.child}>222<{/block}>
然后在子模板直接使用<{block name="writeToPar"}>content of child<{/block}>即可将content of child替换
<{$smarty.block.child}>)。【定界符已改为<{}>】
3、使用 Smarty 的保留变量{$smarty.block.parent}【在子模板中写】作为占位符,将父模板{block}的内容插
入到子模板相应的任何位置。(如:<{block name="writeToChild"}>999<{$smarty.block.parent}>999<{/block}>
然后在父模板写<{block name="writeToChild"}>content of parent<{/block}>即可将content of parent替换
<{$smarty.block.parent}>)。【定界符已改为<{}>】
14、Smarty3 的内置函数
1、三种定义变量的形式
<{assign var="one" value="111"}>
<{assign "one" value="111"}>
<{$one="111"}>
2、数组定义方式
<{assign var="arr" value=[1,2,[3,4]}>
访问:<{$arr[0]}> = 1;<{$arr[2][1]}> = 4.
<{assign "arr" value=['a'=>"apple",'b'=>"blue"]}>
访问:<{$arr.a}> = apple.
3、表达式值赋予变量
<{$x=1}> <{$y=2}>
<{assign var="v" value="`$x+$y`"}>
<{$f=$x+1}>
<{$f=strlen($str)}>
<{$foo=myfunc($x+$y)}>
......
4、append 往数组追加元素
<{append var="arr" value="val"}> => $arr[]="val";
<{append var="arr" value="val" index="first" scope="parent"}> => $arr.first="val";
5、循环语句
{if}{elseif}{else}分支结构
<{if ...}>
...
<{elseif ...}>
<{if ...}>
...
<{/if}>
...
<{else}>
...
<{/if}>
{for}循环
<{for $a=1 to 10}>
<{$a}>
<{/for}>
<{for $a=$start to $end step=num max=mx}> step=num步数为num,max=mx最大值为mx。
<{$a}>
<{forelse}>
...
<{/for}>
{while}循环
<{while $a gt 0}>
<{$a--}><br>
<{/while}>
6、在模板里定义函数并调用函数
定义函数func:
<{function name="func"}> 或简写 <{function func}>
aaaaaaaaaaa //函数体
<{/function}>
调用函数func:
<{func}>
定义函数func和局部变量:
<{function func level=0 v="a"}>
<{$level}>---<{$v}><br>
<{$data}>----<{$style}><br>
bbbbbb<br>
<{/function}>
调用函数func并传递参数:
<{func v="val" data="123" style="free" level="3"}>//传递参数时参数位置可以随意。
也可通过call调用func函数:<{call name=func}> 或 <{call func}>
7、使用foreach、foreachelse遍历数组
<{foreach $arr as $item}>
... <{$item}>
<{foreachelse}>//非必需。
...
<{/foreach}>
<{foreach $arr as $key=>$item}>
...<{$key}> => <{$item}>
<{foreachelse}>
...
<{/foreach}>
<{foreach $arr as $item}>
...<{$item@key}> => <{$item}>
<{foreachelse}>
...
<{/foreach}>
循环次数:<{$item@total}>
<{$item@key}>等价于$key,前者记得加上$item值。
foreach遍历二维数组$data
<{foreach $data as $row}>
<{if $row@first}> <{*判断是否是第一行*}>
<tr bgcolor="blue">
<{elseif $row@last}> <{*判断是否是最后一行*}>
<tr bgcolor="green">
<{elseif $row@index is even}> <{*判断下标是否为偶数(0开始)*}>
<tr bgcolor="yellow">
<{else}>
<tr>
<{/if}>
<td><{$row@index}></td> <{*从0开始递增*}>
<td><{$row@iteration}></td> <{*从1开始递增*}>
<{foreach $row as $col}>
<td><{$col}></td>
<{/foreach}>
</tr>
<{foreachelse}>
数组为空或未被分配过来。
<{/foreach}>
8、使用section、sectionelse遍历数组(索引数组)
<{section loop=$arr name="v"}> //name随便起名
数组下标:<{$smarty.section.v.index}>
访问数组元素:<{$arr[$smarty.section.v.index]}> or <{$arr[v]}>
<{/section}>
解析成for循环如下:
for($i=0;$i<count($arr);$i++){...;}
section遍历二维数组$data
<{section loop=$data name='ls' start="10" step=3 max=10}> //name随便起名
<tr bgcolor="<{if $smarty.section.ls.iteration is even}>yellow<{/if}>">
<td><{$smarty.section.ls.index}></td> <{*受start、step和max参数影响会对应的改变初值及递增的幅度及最大记录数*}>
<td><{$smarty.section.ls.iteration}></td> <{*从1开始递增*}>
<td><{$data[ls].id}></td>
<td><{$data[ls].name}></td>
</tr>
<{sectionelse}>
数组为空或未被分配过来。
<{/section}>
15、输出左右定界符及屏蔽smarty解析(未修改定界符的情况下)
{ldelim}、{rdelim} => "{"、"}"。
{literal}--这里的内容不被smarty解析!--{/literal}
16、{include} 包含
直接在主模板里包含子模板:
<{include file="header.html"}> 或者简写:<{include "header.html"}>
注意:主模板分配的变量可以在子模板中使用,而子模板分配的变量只能在自己模板里使用!
可以使用assign将子模板分配给某个变量,需要时再输出此变量,如下所示:
<{include file="header.html" assign="header"}> <{*此处不输出任何内容*}>
<{$header}> <{*输出模板内容*}>
17、Smarty3缓存控制前的页面静态化原理
1、不去执行数据库连接
2、不去执行SQL语句