必威体育Betway必威体育官网
当前位置:首页 > IT技术

smarty

时间:2019-10-19 22:42:18来源:IT技术作者:seo实验室小编阅读:83次「手机版」
 

smarty

一、           Introduction

模板技术,将php和html分开的技术。常用的模板引擎,smarty、template、fxl template、dwoo,其中,smarty是功能最强大,最常用的。Smarty是一个php的模板引擎技术,提供让程序逻辑与页面显示代码分开的功能。特点,速度快,编译型,缓存技术,插件技术,强大的表现逻辑。

二、           安装与使用

从官网获取,注意版本的支持,为了便于访问,解压缩到工作站的访问根目录下。

使用步骤:

创建相应的文件夹,一般在smarty的解压目录下,创建一个templates目录,用于存放模板,创建一个templates_c,作为编译目录。

在创建的目录的同级目录中,新建一个php文件,如index.php

<?php

//1,引入smarty类

include "libs/Smarty.class.php";

//2,实例化对象

$smarty = new Smarty();

//3,设置相关属性,设置创建的目录

$smarty->template_dir = "templates";//模板目录

$smarty->compile_dir = "templates_c";//编译目录

//4,调用assign方法分配数据

$smarty->assign('title', 'smarty模板');

$smarty->assign('content', 'smarty模板好用');

//5,调用display方法载入模板

$smarty->display('index.html');

编写模板文件

在complates目录创建一个index.html文件。

<!DOCTYPE HTML>

<html>

<head>{$title}</head>

<body>

{$title}

{$content}

</body>

</html>

然后访问这个index.html,就会在templates_c目录下产生编译文件,内容大致为:

<!DOCTYPE HTML>

<html>

<head><?php echo$_smarty_tpl->tpl_vars['title']->value;?>

</head>

<body>

<?php echo $_smarty_tpl->tpl_vars['title']->value;?>

<?php echo $_smarty_tpl->tpl_vars['content']->value;?>

</body>

</html><?php }

}

?>

三、           Smarty语法

(一)前端相关的语法

1.       定界符

默认的定界符是{}。

任何在定界符之外的内容,都是静态的,是不会被解析的,包括php代码;{和$中间不能有任何空格,否则将不会被解析;如果在页面中有css和js,为了防止将css或者js的内容按照smarty语法解析,需要在出现{的地方,空一格,或者不要紧贴着{;默认的定界符是可以修改的。

使用内置函数literal,解决{的冲突,比如: 

      <style>

              h2{

                     color:red;

                     font-size:20px;

              }

              {literal}

              .c1{color:blue;font-size:12px;}

              {/literal}

       </style>

也可通过修改定界符的方法,解决冲突,在index.php中,

$smarty->left_delimiter = "*";

$smarty->right_delimiter = "*";

也可以将css和js以外部方式引入,也避免冲突。

2.       注释

格式:左定界符*内容*右定界符

比如,{*xxxx*}。

3.       变量

在模板中可以使用的变量有3中来源。在php中通过assign方法分配过来的;保留变量;配置变量。

1)       通过assign分配变量

直接使用assign方法,语法,$smarty->assign(名,值)。在php中数据类型,有4种标量类型,整型、浮点型、字符串、布尔;2种复合类型,数组和对象;2种特殊类型,资源和NULL。其中,对于smarty来说,资源类型和NULL是不需要用的,对象可以用,一般不用,需要分配的类型是4种标量和数组类型。

新建一个assign.php文件,内容

<?php

//1,引入smarty类

include "libs/Smarty.class.php";

//2,实例化对象

$smarty = new Smarty();

//3,设置相关属性,设置创建的目录

$smarty->template_dir = "templates";//模板目录

$smarty->compile_dir = "templates_c";//编译目录

$smarty->assign('name', 'haha');

$smarty->assign('do', true);

$smarty->assign('age', 12);

$smarty->assign('money', 12.34);

$smarty->display('assign.tp1');

创建一个assign.tp1文件

<!DOCTYPE html>

<html>

<body>

       <p>{$name}</p>

       <p>{$do}</p>

       <p>{$age}</p>

       <p>{$money}</p>

</body>

</html>

分配数组的例子:

<?php

//1,引入smarty类

include "libs/Smarty.class.php";

//2,实例化对象

$smarty = new Smarty();

//3,设置相关属性,设置创建的目录

$smarty->template_dir = "templates";//模板目录

$smarty->compile_dir = "templates_c";//编译目录

$smarty->assign('name', 'haha');

$smarty->assign('do', true);

$smarty->assign('age', 12);

$smarty->assign('money', 12.34);

//分配数组

$smarty->assign('cont', array('hah1','hah2','哈哈3','哈哈4'));

//关联数组

$smarty->assign('user', array(

              'id' => 1,

              'name' =>'heihei',

              'age' => 22,

              'address' =>'beej',

       ));

$smarty->display('assign.tp1');
<!DOCTYPE html>

<html>

<body>

       <p>{$name}</p>

       <p>{$do}</p>

       <p>{$age}</p>

       <p>{$money}</p>

       <ul>

              <li>{$cont[0]}</li>

              <li>{$cont[2]}</li>

              <li>{$cont[1]}</li>

              <li>{$cont[3]}</li>

              <li>{$cont.3}</li>

       </ul>

       <ul>

              <li>{$user['id']}</li>

              <li>{$user['name']}</li>

              <li>{$user['age']}</li>

              <li>{$user['address']}</li>

              <li>{$user.id}</li>

              <li>{$user.name}</li>

       </ul>

</body>

</html>

2)       保留变量

无需分配,直接在模板中使用,包括smarty本身以及超级全局变量

       <p>{$smarty.now}</p>

       <p>{$smarty.version}</p>

       <p>{$smarty.server.SERVER_NAME}</p>

定义常量

define("ROOT",getcwd());

在模板中使用常量

       <p>{$smarty.const.ROOT}</p>

3)       配置变量

有的数据可以交给前端人员自定义的,比如网站的版权信息。可以用配置变量的方式。

格式:名 = 值

在smarty目录的新建一个configs目录,在这个目录下新建一个site.conf文件,配置如下:

company =haohaogan公司

num = 00010000

使用配置变量,需要载入配置,在模板中使用时,有两种方式{#名#}或者{$smarty.config.名},比如:

       {config_loadfile="site.conf"}

       <p>{#company#}</p>

       <p>{$smarty.config.num}</p>

还可以配置段/节,比如在配置文件中

[duanwu]

color = $00ff00



[zhongqiu]

color = $0000ff

使用方式,在载入时指明使用哪个节:

       {config_loadfile="site.conf" section="duanwu"}

       <p>{#company#}</p>

       <p>{$smarty.config.num}</p>

       <p>{#color#}</p>

       <hr />

4.       内置函数

页面中输出数据的时候,难免对业务逻辑的一些处理,比如需要循环输出。

1)       if   else

php代码

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('qq', 123);

$smarty->display('if.tp1');

模板

<body>

       <h2>你的条件是{$qq}</h2>

       <p class='c1'>最好的选择是

              {if $qq <=50&& $qq > 30}

                     java

              {elseif $qq <= 30&& $qq > 20}

                     php

              {elseif $qq <= 20&& $qq > 10}

                     html

              {else}

                     haha

              {/if}

       </p>

</body>

2)       foreach

处理数组时常用foreach。

格式有两种,为:

{foreach  $arrayvar as  $itemvar}

{foreach  $arrayvar as  $keyvar->$itemvar}

一维数组的例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('user', array('haha1','hah2','哈哈3','哈哈4','哈哈'));

$smarty->display('for.tp1');
<body>

       <ul>

              {foreach $user as$k=>$v}

                     <li>{$k}---{$v}</li>

              {/foreach}

       </ul>

</body>

二维数组的例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('user', array('haha1','hah2','哈哈3','哈哈4','哈哈'));

$userinfo = array(

       array('id'=>1,'name'=>'haha', 'sex'=>1),

       array('id'=>2,'name'=>'haha2', 'sex'=>0),

       array('id'=>3,'name'=>'hah3a', 'sex'=>0),

       array('id'=>4,'name'=>'ha4ha', 'sex'=>1),

);

$smarty->assign('userinfo', $userinfo);

$smarty->display('for.tp1');



       <tablewidth="500" border="1">

              <tr>

                     <th>id</th>

                     <th>姓名</th>

                     <th>性别</th>

              </tr>

              <tr>

                     {foreach$userinfo as $k => $v}

                            <tr>

                                   <td>{$v.id}</td>

                                   <td>{$v['name']}</td>

                                   <td>{$v.sex}</td>

                            </tr>

                     {/foreach}

              </tr>

       </table>

指定字段的时候,使用了两种方式。

在foreach中使用if

       <tablewidth="500" border="1">

              <tr>

                     <th>id</th>

                     <th>姓名</th>

                     <th>性别</th>

              </tr>

              <tr>

                     {foreach$userinfo as $k => $v}

                            <tr

                                   {if$k is odd} class='odd' {/if}

                            >

                                   <td>{$v.id}</td>

                                   <td>{$v['name']}</td>

                                   <td>{$v.sex}</td>

                            </tr>

                     {/foreach}

              </tr>

       </table>

Foreach的一些属性,如表:

@index

当前数组索引,从0开始

@iteration

当前循环的次数,从1开始计算

@first

首次循环时,值为true

@last

循环到最后一次时,值为true

@total

总的循环次数,可在foreach内部使用,也可以在循环完成后使用

@show

在foreach循环执行完之后,检测循环是否显示数据的判断

比如:

       <tablewidth="500" border="1">

              <tr>

                     <th>id</th>

                     <th>姓名</th>

                     <th>性别</th>

              </tr>

              <tr>

                     {foreach$userinfo as $k => $v}

                            <tr

                                   {if$v@iteration is odd} class='odd' {/if}

                            >

                                   <td>{$v.id}</td>

                                   <td>{$v['name']}</td>

                                   <td>{$v.sex}</td>

                            </tr>

                     {/foreach}

              </tr>

       </table>

3)       section

用于遍历数组,但是只能遍历数字连续的索引数组。

例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('user', array('haha1','hah2','哈哈3','哈哈4','哈哈'));

$smarty->display('section.tp1');
<body>

       <ul>

              {section name ='index' loop = '4'}

                     <li>{$user[index]}</li>

              {/section}

       </ul>

</body>

不可以用section来遍历关联数组。如果loop=$数组名,就是遍历整个数组。比如,loop=$user。

5.       变量修饰器

有时候,在模板中使用数据,还需要做进一步的处理,而且只能在模板层面来处理。比如,在完成无限分类的展示的时候,按照层级来进行显示。显示效果不直观,需要进一步处理。对此,可以使用变量修饰器,也称为变量调节器。Smarty提供的变量修饰器很多。比如:

       <p>{$smarty.now}</p>

       <p>{$smarty.now|date_format:'%Y-%m-%d%H:%M:%S'}</p>

例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('haha', '哈aa哈bb哈哈哈,嘿嘿嘿嘿嘿嘿,呵呵呵呵hhheee');

$smarty->display('modifer.tp1');
<!DOCTYPE HTML>

<html>

<head>

       <style>

              .odd{

                     background-color:grey;

              }

       </style>

</head>

<body>

       <p>{$smarty.now}</p>

       <p>{$smarty.now|date_format:'%Y-%m-%d%H:%M:%S'}</p>

       <hr />

       <p>{$haha}</p>

       <p>{$haha|truncate:10:'***'|upper}</p>

</body>

</html>

指定输出的次数,比如5次。

$smarty->assign('times',5);
<body>

       <p>{$smarty.now}</p>

       <p>{$smarty.now|date_format:'%Y-%m-%d%H:%M:%S'}</p>

       <hr />

       <p>{$haha}</p>

       <p>{$haha|truncate:10:'***'|upper}</p>

       <p>{'hello'|str_repeat:$times}</p>

</body>

6.       函数插件

Smarty自带了一些自定义的函数插件,可以在模板中使用,常见的有单选框、复选框、下拉列表、cycle等。

1)       单选框

例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('user', array('u1', 'u2', 'u3', 'u4'));

$smarty->assign('user2', array(

              '0' => 'u1',

              '1' => 'u2',

              '2' => 'u3',

              '3' => 'u4',

       ));

$smarty->display('radio.tp1');
<!DOCTYPE HTML>

<html>

<head>

       <style>

              .odd{

                     background-color:grey;

              }

       </style>

</head>

<body>

       <p>请选择</p>

       {html_radiOS name='user' values=$useroutput=$user selected='u1'}

       <hr />

       {html_radios name='user2'options=$user2 selected='2'}

       <hr />

       {html_radios name='user3'options=$user selected='3'}

</body>

</html>

2)       复选框

例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('user', array('u1', 'u2', 'u3', 'u4'));

$smarty->assign('selected', array('u1', 'u3'));

$smarty->display('checkbox.tp1');
<!DOCTYPE HTML>

<html>

<head>

       <style>

              .odd{

                     background-color:grey;

              }

       </style>

</head>

<body>

       <p>请选择</p>

       {html_checkboxesname='user[]' values=$user output=$user selected=$selected}

       <hr />

       {html_checkboxesname='user[]' values=$user options=$user selected='1'}

       <hr />

</body>

</html>

3)       下拉列表

例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('user', array('u1', 'u2', 'u3', 'u4'));

$smarty->assign('selected', array('u1', 'u3'));

$smarty->display('select.tp1');
<!DOCTYPE HTML>

<html>

<head>

       <style>

              .odd{

                     background-color:grey;

              }

       </style>

</head>

<body>

       <p>请选择</p>

       {html_options name='user'values=$user output=$user selected='u1'}

       <hr />

       {html_options name='user'values=$user options=$user selected='1'}

       <hr />

</body>

</html>

4)       cycle

例子:

<?php

//引入smarty

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('user', array('u1', 'u2', 'u3', 'u4'));

$userinfo = array(

       array('id'=>1,'name'=>'haha', 'sex'=>1),

       array('id'=>2,'name'=>'haha2', 'sex'=>0),

       array('id'=>3,'name'=>'hah3a', 'sex'=>0),

       array('id'=>4,'name'=>'ha4ha', 'sex'=>1),

);

$smarty->assign('userinfo', $userinfo);

$smarty->display('cycle.tp1');
<!DOCTYPE HTML>

<html>

<head>

       <style>

              .odd{

                     background-color:grey;

              }

       </style>

</head>

<body>

       <tablewidth="500" border="1">

              <tr>

                     <th>id</th>

                     <th>姓名</th>

                     <th>性别</th>

              </tr>

              <tr>

                     {foreach$userinfo as $k => $v}

                            <tr

                                   {if$k is odd} class='odd' {/if}

                            >

                                   <td>{$v.id}</td>

                                   <td>{$v['name']}</td>

                                   <td>{$v.sex}</td>

                            </tr>

                     {/foreach}

              </tr>

       </table>

       <hr />

       <tablewidth="500" border="1">

              <tr>

                     <th>id</th>

                     <th>姓名</th>

                     <th>性别</th>

              </tr>

              <tr>

                     {foreach$userinfo as $k => $v}

                            <trclass= "{cycle values = 'odd,even'}">

                                   <td>{$v.id}</td>

                                   <td>{$v['name']}</td>

                                   <td>{$v.sex}</td>

                            </tr>

                     {/foreach}

              </tr>

       </table>

</body>

</html>

(二)php开发相关的smarty使用

1.       在项目中引入smarty

放到framework目录或者APPlication目录中都可以。如果放到framework,就是把smarty作为框架的一部分,thinkphp。如果放到application中,就是将smarty作为第三方文件引入,比如CI框架。

以作为第三方引入,在application目录下新建third_party目录,将smarty目录中的libs目录拷贝到这个目录下,并重命名为smarty。

然后在首页中载入smarty类,在视图目录中创建模板目录和编译目录,将视图文件转移到templates目录下,比如:

在主页修改代码,载入smarty,和使用smarty显示

       //index方法

       public functionindexAction(){

              //获取所有的商品分类

              $categoryModel = newCategoryModel('category');

              $cats =$categoryModel->frontCats();

              //echo"<pre>";

              //var_dump($cats);die;

              //获取推荐商品

              $goodsModel = newGoodsModel('goods');

              $bestGoods =$goodsModel->getBestGoods();

              //载入smarty类

              include APP_PATH ."third_party/smarty/Smarty.class.php";

              //实例化smarty类

              $smarty = newSmarty;

              //设置模板目录和编译目录

              $smarty->template_dir= CUR_VIEW_PATH . "templates";

              $smarty->compile_dir= CUR_VIEW_PATH . "templates_c";

              //分配数据

              $smarty->assign('cats',$cats);

              $smarty->assign('bestGoods',$bestGoods);

              //载入视图

              $smarty->display('index.html');

              //includeCUR_VIEW_PATH . 'index.html';

       }

然后在,在显示页面,使用smarty的语法获取数据,比如:

{foreach $cats as $k => $v}

       <!-- <?php if ($k< 8):?> -->

       {if $k < 8}

       <li id="cat_1"class="">

              <h3><ahref="" title="男女服装"><!-- <?php echo$v['cat_name'];?> -->{$v.cat_name}</a></h3>

              <pid="cat_1_menu" class="cat_menu clearfix"style="">

                     <!--<?php foreach ($v['child'] as $v1):?> -->

                     {foreach$v.child as $v1}

                     <dlclass="clearfix">

                            <dt><ahref="女装" href=""><!-- <?php echo$v1['cat_name'];?> -->{$v1.cat_name}</a></dt>

                            <dd>

                                   {foreach$v1.child as $v2}

                                   <!--<?php foreach ($v1['child'] as $v2):?> -->

                                   <ahref=""><!-- <?php echo $v2['cat_name'];?>-->{$v2.cat_name}</a>

                                   {/foreach}

                                   <!--<?php endforeach;?> -->

                            </dd>

                     </dl>

                     {/foreach}                                

                     <!--<?php endforeach;?> -->

              </p>

       </li>

       {/if}

       <!-- <?phpendif;?> -->

{/foreach}

<!-- <?php endforeach;?> -->

          

2.       改进引入,提高代码复用率

在home端创建一个Basecontroller,以供继承。

<?php

//

class BaseController extends Controller {

       protected $smarty;

       //构造方法

       public function__construct(){

              //载入smarty类

              include APP_PATH ."third_party/smarty/Smarty.class.php";

              //实例化smarty类

              $this->smarty =new Smarty;

              //设置模板目录和编译目录

              $this->smarty->template_dir= CUR_VIEW_PATH . "templates";

              $this->smarty->compile_dir= CUR_VIEW_PATH . "templates_c";

       }

}

然后,在前端的控制器中,继承这个基础类,只需要修改分配数据和显示模板的代码就可以。

<?php

//前台首页控制器

class IndexController extends BaseController {

       //index方法

       public function indexAction(){

              //获取所有的商品分类

              $categoryModel = newCategoryModel('category');

              $cats =$categoryModel->frontCats();

              //echo"<pre>";

              //var_dump($cats);die;

              //获取推荐商品

              $goodsModel = newGoodsModel('goods');

              $bestGoods =$goodsModel->getBestGoods();

              /*//载入smarty类

              include APP_PATH ."third_party/smarty/Smarty.class.php";

              //实例化smarty类

              $smarty = newSmarty;

              //设置模板目录和编译目录

              $smarty->template_dir= CUR_VIEW_PATH . "templates";

              $smarty->compile_dir= CUR_VIEW_PATH . "templates_c";*/

              //分配数据

              $this->smarty->assign('cats',$cats);

              $this->smarty->assign('bestGoods',$bestGoods);

              //载入视图

              $this->smarty->display('index.html');

              //includeCUR_VIEW_PATH . 'index.html';

       }

}

3.       模板包含

将很多页面中都有的相同部分,比如头部信息,使用模板包含显示。

首先将头部信息,单独的保存为header.html。

然后,将公共头部中需要获取数据的功能,交给BaseController中的index方法。

  {include file ='header.html'}

  </p>

4.       模板继承

在比较大型的网站中,很多页面会有不止一处的内容相同的部分。使用模板的继承来实现可以达到可重用和可扩展的效果。

用法一般是定义一个父模板,定义公共的内容,通常称之为模板布局;定义一个子模板,继承自父模板,使用extends函数实现。

比如:

定义父模板

<!DOCTYPE html>

<html lang="en">

<head>

       <meta charset="UTF-8">

       <title>Document</title>

</head>

<body>

       <pclass="header">

              头部信息

       </p>

       <pclass="main">

              <pclass="menu">

                     控制面板

              </p>

              {block name ="content"}

                     <pclass="content">

                            具体内容

                     </p>

              {/block}

       </p>

       <pclass="footer">

              底部版权信息

       </p>

</body>

</html>

编写调用smarty的php

<?php

//1.载入smarty类

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";



$smarty->display('user.tpl');

编写子模板

{extends file ='layout.tpl'}

在子模板中,需要覆盖父模板的内容,或者重新定义,可以直接声明block即可。比如:

{extends file = 'layout.tpl'}

{block name = "content"}

       <pclass="content">

              商品详情

       </p>

{/block}

注意,在子模板中,只有extends中继承的和block中重新定义的才能显示。

使用{$smarty.block.child}布局可以调用子级的内容,{$smarty.block.parent}子级页面可以调用父级页面内容。

比如,使用一套模板,实现两种显示页面的效果。

在父模板定义嵌套的block

<body>

       <pclass="header">

              头部信息

       </p>

       {block name ="main"}

              <pclass="main">          

                     <pclass="menu">

                            控制面板

                     </p>

                     {block name ="content"}

                            <pclass="content"></p>

                     {/block}        

              </p>

       {/block}

       <pclass="footer">

              底部版权信息

       </p>

</body>

在不同的子模板中实现不同的block的内容

{extends file = 'layout.tpl'}

{block name = "content"}

       <pclass="content">

              商品详情

       </p>

{/block}



{extends file = "layout.tpl"}

{block name = "main"}

       <p class="main">

              购物车

       </p>

{/block}

注意,如果页面的公共部分不多,用模板包含就行,如果比较多,使用模板继承。

5.       插件扩展

在页面中输出的时候,smarty提供的变量修饰器以及php函数都不能满足,此时就需要扩展。

扩展要写在libs/plugins目录下。

例子:

<?php

//自定义变量修饰器

function smarty_modifier_mytool($string,$param) {

       $string .= $param;

       return $string;

}

然后调用smarty

<?php

//1.载入smarty类

include "libs/Smarty.class.php";

$smarty = new Smarty();

$smarty->template_dir = "templates";

$smarty->compile_dir = "templates_c";

$smarty->assign('text', '内容内容');

$smarty->display('mytool.tpl');

使用自定的变量修饰器

<body>

       {$text|mytool:'哈哈哈'}

</body>

四、           Smarty的缓存

缓存就是将数据保存到某个硬件或者软件当中,便于快速的访问。根本上都是在内存中。常见的缓存形式有两种,数据缓存和页面缓存。

数据库的角度看,有些数据不是经常变化的,可以把它缓存起来,以后访问的时候,可以直接访问缓存,提升效率。比如使用memcached技术。

文件缓存,也称为页面缓存。有的页面,一旦生成,就不再变化,可以将这些页面缓存起来,直接将其转成静态页面,后续的访问就是直接访问静态页面,极大提升了效率。使用页面静态化技术可以实现。

smarty也实现了缓存,实现的是文件缓存。

1.       smarty缓存的使用

在基础类中设置缓存相关的内容。为了起到缓存的作用,在取数据之前,需要做一个判断,判断当前的缓存是否有效,如果有效,则无需使用模型取数据。Smarty提供了一个函数,isCached(模板名称)。

在基础类中

<?php

//

class BaseController extends Controller {

       protected $smarty;

       //构造方法

       public function__construct(){

              //载入smarty类

              include APP_PATH ."third_party/smarty/Smarty.class.php";

              //实例化smarty类

              $this->smarty =new Smarty;

              //设置模版目录和编译目录

              $this->smarty->template_dir= CUR_VIEW_PATH . "templates";

              $this->smarty->compile_dir= CUR_VIEW_PATH . "templates_c";

              //开启缓存

              $this->smarty->caching= true;

              //设置缓存目录

              $this->smarty->cache_dir= CUR_VIEW_PATH . "cache";

              //设置缓存的有效期

              $this->smarty->cache_lifetime= 60;

              //开启调试模式

              $this->smarty->debugging= true;

              //判断缓存是否有效,如果失效则获取数据

              if (!$this->smarty->isCached('index.html') ) {

                     $categoryModel= new CategoryModel('category');

                     $cats =$categoryModel->frontCats();

                     $this->smarty->assign('cats',$cats);

              }            

              $this->smarty->assign('index',false);

       }

}

在首页控制器类中

       //index方法

       public functionindexAction(){

              /*//获取所有的商品分类

              $categoryModel = newCategoryModel('category');

              $cats =$categoryModel->frontCats();*/

              //echo"<pre>";

              //var_dump($cats);die;

              //获取推荐商品

              //判断缓存是否失效

              if (!$this->smarty->isCached('index.html') ) {

                     $goodsModel =new GoodsModel('goods');

                     $bestGoods =$goodsModel->getBestGoods();

                     $this->smarty->assign('bestGoods',$bestGoods);

              }

             

              /*//载入smarty类

              include APP_PATH ."third_party/smarty/Smarty.class.php";

              //实例化smarty类

              $smarty = newSmarty;

              //设置模版目录和编译目录

              $smarty->template_dir= CUR_VIEW_PATH . "templates";

              $smarty->compile_dir= CUR_VIEW_PATH . "templates_c";*/

              //分配数据

              //$this->smarty->assign('cats', $cats);

             

              $this->smarty->assign('index',true);

              //载入视图

              $this->smarty->display('index.html');

              //includeCUR_VIEW_PATH . 'index.html';

       }

缓存失效的情况,已经过了有效期的设置值,缓存文件被删除,模板文件被修改。

2.       局部不缓存

一旦页面使用了缓存,那么整个页面的内容就不会变化。实际中,在某些页面,需要动态的展示信息,比如时间,用户状态。这就需要在在页面中,有局部的内容不缓存。Smarty提供了局部不缓存的技术。

有三种方式:

标签的缓存控制,即在标签中使用nocache属性,适合于单个标签;

<body>

       <p>{$smarty.now|date_format:"%Y-%m-%d%T"}</p>

       <p>{$smarty.now|date_format:"%Y-%m-%d%T" nocache}</p>

</body>

变量的缓存控制,即在分配变量时设置第三个参数为true,适用于单个变量;

$smarty->assign('time', $time);

$smarty->assign('time1', $time, true);

模板区域缓存控制,即在模板页面中使用{nocache}{/nocache},适用于一块模板。

       {nocache}

              <p>{$smarty.now|date_format:"%Y-%m-%d%T"}</p>

              <p>{$smarty.now|date_format:"%Y-%m-%d%T"}</p>

       {/nocache}

3.       单模板多缓存

比如,在商品详情页,如果只是在商品控制器中设置一次判断缓存失效,然后获取数据加载数据的动作,那么在所有的商品都被定位到首次点击的的那个商品的缓存文件。所以,需要将每个商品单独的生成一个缓存文件,这就是单模板多缓存。需要在display的时候,传递第二个参数,用来标识当前的内容。比如:

       public functionindexAction(){

              $goods_id =$_GET['goods_id'] + 0;

              if (!$this->smarty->isCached('goods.html', $goods_id) ) {

                     $goodsModel =new GoodsModel('goods');

                     $goods =$goodsModel->selectByPk($goods_id);

                     //var_dump($goods);die;

                     //分配数据

                     $this->smarty->assign('goods',$goods);

              }

              //载入视图

              $this->smarty->display('goods.html',$goods_id);

       }

4.       缓存组

针对需要缓存的内容中根据不同的类别,有不同的属性信息的情况,比如商品列表,服装的属性和家电的属性就不同,可以使用缓存组来达到缓存的效果。实际上是单模板多缓存的一种更为细致的方法。是一种用空间换取时间的方案

比如:

<?php

class ListController extends BaseController {

       public functionindexAction(){

              $cat_id =$_GET['cat_id'] + 0;

              //获取对应的数据

              $size =isset($_GET['size']) ? $_GET['size'] : "";

              $brand =isset($_GET['brand']) ? $_GET['brand'] : "";

              $style =isset($_GET['style']) ? $_GET['style'] : "";

              $material =isset($_GET['material']) ? $_GET['material'] : "";



              $this->smarty->display("list.html","$size|$brand|$style|$material");             

       }

}

5.       删除缓存

缓存失效的情况,已经过了有效期的设置值,缓存文件被删除,模板文件被修改。一般,在后台会提供一个操作,用于清除缓存

Smarty提供了删除缓存的方法:clearCache,删除指定模板的缓存;clearAllCache,删除所有缓存。

比如,在控制器中增加一个方法,用于清除缓存。

       public functionclearAction(){

              $this->smarty->clearCache('index.html');

              //指定id清除

              $this->smarty->clearCache('goods.html',2);

              //删除所有

              $this->smarty->clearAllCache();

       }

五、           自定义模板引擎

1.       模板引擎原理

将php文件通过访问模板文件,如果有缓存,使用缓存中的编译文件;如果有混编文件,就访问之;如果没有,就调用smarty引擎,编译文件,将数据显示在模板文件。

2.       自定义模板引擎

基本步骤:

1)       创建目录结构

创建一个tpl目录,在这个目录下创建templates、templates_c、cache、libs4个目录和一个index.php文件。

Index.php的内容,比如:

<?php

// 载入模板类

include "libs/Template.class.php";

// 实例化模板类对象

$tpl = new Template();

//设置模板和编译目录

$tpl->template_dir = "templates";

$tpl->compile_dir = "templates_c";

//分配变量

$tpl->assign('title', '自定义模板引擎');

$tpl->assign('content', '使用自定义模板实现smarty功能');

$tpl->assign('haha', true);

$tpl->assign('user', array('us1', 'us2', 'u好','看看'));

//载入模板

$tpl->display('index.tpl');

定义一个模板文件,用于测试

<!DOCTYPE html>

<html lang="en">

<head>

       <metacharset="UTF-8">

       <title>Document</title>

</head>

<body>

       <h3>{$title}</h3>

       <p>{$content}</p>

       <p>

              {if $haha}

                     哈哈

              {else}

                     heie

              {/if}

       </p>

       <ul>

              {foreach $user as $k=> $v}

                     <li>{@k}--{@v}</li>

              {/foreach}

       </ul>

</body>

</html>

2)       定义template类

<?php

//模板类

class Template {

       //保存变量的数组属性

       private $tpl_vars =array();

       //模板目录

       public $template_dir ="templates";

       //编译目录

       public $compile_dir ="templates_c";

       //分配变量方法

       public function assign($name,$value){

              if (!empty($name)) {

                     $this->tpl_vars[$name]= $value;

              } else {

                     exit('请设置变量名');

              }

             

       }

       //载入模板方法

       public functiondisplay($file){

              //编译

              $tplFile =$this->template_dir . "/{$file}";//模板文件名

              $compileFile =$this->compile_dir . "/" . md5($file) . ".$file.php";//编译文件名

              $content =file_get_contents($tplFile);



              file_put_contents($compileFile,$content);



              include$compileFile;

       }

}

3)       关于正则表达式

在解析模板文件中的{}中的内容时,不管其中是变量还是控制语句时,需要能够锁定{},这就需要使用到正则表达式的知识。

正则表达式,就是用一些特定的符号和语法,来对字符串进行匹配,一般是匹配某种格式。

正则中,常用的元字符

.

匹配除换行意外的任意字符

\w

匹配字母或数字或下划线或汉字

\s

匹配任意的空白符

\d

匹配数字

\b

匹配单词的开始或结束

^

匹配字符串的开始

$

匹配字符串的结束

常用的限定符

*

重复零次或更多次

+

重复一次或更多次

?

重复零次或一次

{n}

重复n次

{n, }

重复n次或更多次

{n,m}

重复n到m次

比如,匹配手机号,\d{11};匹配qq,\d{5, }。

对于一些特殊字符,需要转移,使用\就可以,比如{  \{,\   \\,/   \/,$  \$。 

上例中,要找到{$content},还要引用,这是反向引用。通过两步实现,捕获,将需要查找的内容放在小括号()中;引用,使用 \数字 的方式,比如\1表示第一个小括号,\2表示第二个小括号中的,类推。使用\1时需要转义,如\\1。

使用正则的时候,注意的细节,正则表达式应该放在//之间,使用单引号引用。

4)       定义parse类

<?php

//解析类

class Parse {

       //解析内容

       private $content;

       //构造方法

       public function__construct($content){

              $this->content =$content;

             

       }

       //解析方法

       public function parse(){

              $this->parseVar();

              $this->parseIf();

              $this->parseFor();

              return$this->content;

       }

       //解析普通变量

       /**

        * 源:{$title}{$content}

        * 目标:<?php echo $this->tpl_vars['title'];?>

        */

       public function parseVar(){

              $pattern ='/\{\$(\w+)\s*\}/';

              if(preg_match($pattern, $this->content)) {

                     $this->content= preg_replace($pattern, "<?php echo \$this->tpl_vars['\\1'];?>", $this->content);

              }

       }

       //解析if语句

       /*

       源:{if$haha}

                            哈哈

                     {else}

                            heie

                     {/if}

       目标:

              <?php if($haha):?>

                     哈哈

              <?php else :?>

                     heie

              <?php endif;?>

        */

       public function parseIf(){

              $patternIf ='/\{if\s+\$(\w+)\s*\}/';

              $patternEnd ='/\{\/if\s*\}/';

              $patternElse ='/\{else\s*\}/';

              if(preg_match($patternIf, $this->content)) {

                     if(preg_match($patternEnd, $this->content)) {

                            $this->content= preg_replace($patternIf,

                                   "<?phpif (\$this->tpl_vars['\\1']):?>", $this->content);

                            $this->content= preg_replace($patternEnd, "<?php endif; ?>",$this->content);

                            //判断有没有else

                            if(preg_match($patternElse, $this->content)) {

                                   $this->content= preg_replace($patternElse, "<?php else: ?>",$this->content);

                            }

                     } else {

                            exit('模板语法错误');

                     }

              }



       }

       //解析foreach语句

       /*

       源:            

              {foreach $user as $k=> $v}

                     <li>{@k}--{@v}</li>

              {/foreach}

       目标:

              <?php foreach($this->tpl_vars['user'] as $k => $v):?>

                     <li><?phpecho $k;?>--<?php echo $v;?></li?>

              <?phpendforeach;?>

        */

       public function parseFor(){

              $patternFor ='/\{foreach\s+\$(\w+)\s+as\s+\$(\w+)\s*=>\s*\$(\w+)\s*\}/';

              $patternEnd ='/\{\/foreach\s*\}/';

              $patternVar ='/\{@(\w+)\s*\}/';

              if(preg_match($patternFor, $this->content)) {

                     if(preg_match($patternEnd, $this->content)) {

                            $this->content= preg_replace($patternFor, "

                                   <?phpforeach (\$this->tpl_vars['\\1'] as \$\\2 => \$\\3):?>



                                   ",$this->content);

                            $this->content= preg_replace($patternEnd, "<?php endforeach;?>",$this->content);

                            if(preg_match($patternVar, $this->content)) {

                                   $this->content= preg_replace($patternVar, "<?php echo \$\\1;?>",$this->content);

                            }

                     }

              } else {

                     exit('模板语法错误');

              }

       }

}

3.       完善template类

在temlate对目标文件进行编译前,需要进行判断,如果编译文件存在并且编译文件是有效的。判断模板文件是否被修改,如果模板文件被修改,则需要重新编译。判断文件是否被修改,可以通过文件的修改时间来判断。

正常,先有模板文件,然后才有编译文件,filemtime(模板文件)<filemtime(编译文件)。如果模板文件被修改了,那么filemtime(模板文件)>filemtime(编译文件)。

<?php

//模板类

class Template {

       //保存变量的数组属性

       private $tpl_vars =array();

       //模板目录

       public $template_dir ="templates";

       //编译目录

       public $compile_dir ="templates_c";

       //分配变量方法

       public functionassign($name, $value){

              if (!empty($name)) {

                     $this->tpl_vars[$name]= $value;

              } else {

                     exit('请设置变量名');

              }

             

       }

       //载入模板方法

       public functiondisplay($file){

              //编译

              $tplFile =$this->template_dir . "/{$file}";//模板文件名

              $compileFile =$this->compile_dir . "/" . md5($file) . ".$file.php";//编译文件名

              //如果编译文件不存在或者模板文件被修改,则重新编译

              if(!file_exists($compileFile) || filemtime($tplFile) >filemtime($compileFile)) {

                     echo "进行编译";

                     //编译

                     $content =file_get_contents($tplFile);

                     //引入parse类

                     include"libs/Parse.class.php";

                     //实例化对象

                     $parse = newParse($content);

                     //调用解析方法完成解析

                     $content =$parse->parse();

                     file_put_contents($compileFile,$content);

              }            

              //载入编译文件

              include$compileFile;

       }

}

4.       实现缓存

分两种情况

第一次生成缓存的过程,需要时候用ob缓冲区,开启缓冲区,生成缓存文件;

后续的访问,如果有缓存,直接访问缓存。

<?php

//模板类

class Template {

       //保存变量的数组属性

       private $tpl_vars =array();

       //模板目录

       public $template_dir ="templates";

       //编译目录

       public $compile_dir ="templates_c";

       //设置缓存目录

       public $cache_dir ="cache";

       //是否开启缓存

       public $caching = false;//默认不开启

       //开启缓冲区

       public function__construct(){

              ob_start();

       }

       //分配变量方法

       public functionassign($name, $value){

              if (!empty($name)) {

                     $this->tpl_vars[$name]= $value;

              } else {

                     exit('请设置变量名');

              }

             

       }

       //载入模板方法

       public functiondisplay($file){

              //编译

              $tplFile =$this->template_dir . "/{$file}";//模板文件名

              $compileFile =$this->compile_dir . "/" . md5($file) . ".$file.php";//编译文件名

              $cacheFile =$this->cache_dir . "/" . md5($file) . ".{$file}";//缓存文件名

              //如果缓存文件存在且有效,直接访问缓存文件

              if(file_exists($cacheFile) && file_exists($compileFile) &&filemtime($tplFile) <= filemtime($compileFile)) {

                     echo "进入缓存";

                     include$cacheFile;

                     return;

              }

              //如果编译文件不存在或者模板文件被修改,则重新编译

              if(!file_exists($compileFile) || filemtime($tplFile) >filemtime($compileFile)) {

                     //echo "进行编译";

                     //编译

                     $content =file_get_contents($tplFile);

                     //引入parse类

                     include"libs/Parse.class.php";

                     //实例化对象

                     $parse = newParse($content);

                     //调用解析方法完成解析

                     $content =$parse->parse();

                     file_put_contents($compileFile,$content);

              }     

              //载入编译文件

              include$compileFile;

              //判断是否开启缓存

              if($this->caching) {

                     //生成缓存文件

                     $data =ob_get_contents();

                     //生成缓存文件

                     file_put_contents($cacheFile,$data);

                     ob_end_clean();

                     include$cacheFile;

              }                   

       }

}

六、           emmet

老名字叫做Zencoding。一款让代码书写更快的插件。

1.       用法

展开的快捷键,ctrl + E

html:xt

html:5

p

p.header

p#box

p>h2

h2+p

p>ul>li*5>a+span

input[type=’text’]

2.       安装

登陆官网下载安装。一般,高版本的sublime或者editplus都已经安装。

相关阅读

Smarty Uninstalle4 智能卸载工具 免费安装及激活教程

Smarty Uninstalle如何激活?今天小编整理了关于Smarty Uninstalle 智能卸载工具中文安装及激活教程,激活方法亲测有效,操作过程相当

分享到:

栏目导航

推荐阅读

热门阅读