PHP本身就是一种标签语言, <?php echo $title; ?>

允许代码用标签的形式任意嵌套在html,

因此,我们可以用PHP自身的这种特性,完成controllerview的分离.

 

1:Smarty可以协助我们分离PHPhtml代码就是记html制作人员看不到PHP标签

 2:也可以对网站进行缓存(重要)

3:面试是要用到

4:体会模板的思想

 

 

1:Cotrollerview的分离是一种功能上的分离,是一种分工的思想.

phphtml代码的分离,仅是代码层面或视觉层面上的分离.

 

2:smartyMVC有什么关系?

没关系.

Smarty完成的仅是代码分离.

 

3:不用smarty,仍然是能够完成MVC模式的开发

 

 

Smarty的一些负面思考:

1:混杂在HTML代码中smarty标签和PHP代码.

对于web前端开发人员来说,没有实质区别

 

2:在实际开发中,html模板-->smarty模板的制作,依然是由PHPer来完成的

 

3:解析,编译本身消耗性能

 

4:增多了很多变量,(页面内的变量,都要赋值到smarty对象-->_tpl_vars 属性上,多了一个变量的副本)

 

 

Smarty模板类的工作流程

1:引入smarty模板类

2:assign赋值把外界变量传到对象内部(存在一个属性上)

3:display (编译模板,把标签模板编译成 html+php混杂的形式)

4:运行编译后的模板

 

 


Smarty的引入

Smarty是一个类引入过程与普通的类没有区别

1:include,require包含此文件

2:实例化

 

 

Smarty的配置

$template_dir    =  'templates';  // 模板文件的所在目录

$compile_dir     =  'templates_c'; // 编译后的文件所在目录

$config_dir      =  'configs'; // 允许独立的配置文件存在,并且配置文件如果多了,允许单独放在一个目录里,

$cache_dir = 'cache'  // 代表缓存文件的存放目录

plugins_dir     =  array('plugins','p2','p3');  // 插件目录(如果自行开发插件,可能会用到)

 

left_delimiter  =  '{';  // 标签的左分界符

Right_delimiter = '}'   // 标签的右分界符

Caching = 0/1/2 // 是否开启缓存

cache_lifetime = 3600 秒 // 缓存生命周期

 

Smarty的赋值

1: $smarty->assign('key',value);   

发生的变化$smarty->_tpl_vars[key] = value;

 

2: 如果assign($arr)中的第一个参数是数组

则会循环数组,把数组的每一个单元追加到_tpl_vars属性上

 

3:append追加赋值

如果需要把多个值,赋给同一个标签变量不必把多个值形成数组然后赋值,

可以通过append,往一个标签反复追加值.

 

:

$smarty->append('goods','自行车');

$smarty->append('goods','火车');

此时推论 $smarty->_tpl_vars['goods'] = array(自行车,火车);

 

如果append进去的值是数组,并且第3merge参数为true,则会把数组单元逐个添加到goods数组里去.

$smarty->append('goods',array('name'=>'刘备','age'=>28),true);

此时, $smarty->_tpl_vars['goods'] = array(自行车,火车,'name'=>'刘备','age'=>28);

 

如果是$smarty->append('goods',array('name'=>'刘备','age'=>28),false);

此时, $smarty->_tpl_vars['goods'] = array(自行车,火车,array('name'=>'刘备','age'=>28));

Smarty模板中,对变量的引用 

变量来源

1:assign赋值得到的变量 存储在_tpl_vars属性中

2:$smarty系统变量对于cookie,session,get,post,$_SERVER等信息,存储在_smarty属性中

Smarty会自动捕捉,并保存起来,形成系统变量,可以直接用标签来引用.

3:从配置文件读取的变量 存储在_config属性中

 

1.1 对于assign赋值得到的变量

对于字符串型,数值型直接通过 $标签名 来引用

 

1.2 对于数组变量

如果键是字符串,则用$标签名.

如果键是数字则用 $标签名[]

 

1.3 对于对象方式

$标签名->属性名 来引用对象的属性值

$标签名->方法() 来调用对象的方法的返回值

 

 

2.1 smarty中的系统变量

$smarty开头

: $smarty.now, 被 解析成 time();

$smarty.get.key ---> $_GET[key]

$smarty.const.常量名 ---> echo 常量名

 

 

3.1 从配置文件得到的变量

配置文件可以用来存储常用且很少变的数据,比如网站名,备案号

通过配置文件得到这些信息,不必去读数据库,可以省一些数据库的开销.

 

配置文件的写法;

配置项1=1

配置项2=2

 

配置文件的载入

Config_load  file="xxx.conf" 

 

配置文件中变量的引用

$smarty.config.配置项

或者 #配置项#

 

 


模板中的逻辑控制

MVC的角度看,在模板中加逻辑控制不正确的,

但是有时,不同的场景下,模板的差异非常小时就比较适合在模板里加逻辑控制,

可以减少模板的数量.

 

If控制结构

{if 表达式}

....

....

{/if}

 

If else 控制结构

{if 表达式}

...

....

{else}

....

....

{/if}

 

If elseif 控制结构

{if  表达式}

...

...

{else if 表达式}

...

...

{/if}

 

 

 


Smarty中的foreach控制结构

要循环谁某个数组 A

当前循环的单元的键赋给哪个临时变量 B

当前循环的单元的值赋给哪个临时变量 C

 

{foreach from=$tag key=k ietm=c

.....

.....

....

{/foreach}

 

foreach完成表格隔行换色功能

$smarty->_foreach 属性是一个数组

如果smartyforeachname属性name="abc"

smarty->_foreach['abc'] = array(total=>循环体个数,iteration=0);  

然后每循环一次,iteration 递增1

 

可以引用$smarty.foreach.foreahcname.key的属性

Key =

total : 循环个数

Iteration: 当前循环次数

Index : 当前索引, iteration-1

First: 判断是否是第1次循环

Last: 判断是否是最后一次循环

 

 

注意:foreachname不能重复

 

Foreach中的key=k, item=v

会影响到同名的标签,请注意,标签不要和foreach中的标签同名.

 


Smarty中数学运算 &比较运算 逻辑运算

Smarty比较运算符

>,<,>=,<=,!=,==,PHP中一样.

Smarty对比较运算符做了一个扩充

如 gt(>),lt(<), gte(>=), eq(==), 不一一列举,可以在smarty_comilper.class.php1330

左右看到比较运算符的扩充情况.

|| &&, or and

 

标签中可以进行数学的+1*/%运算,

但是注意,

1:运算符两边不要有空格

2:运算表达式应以标签开头

Smarty中的"变量调节器"

:{$intro|upper},会把$info的内容转换为大写

原理:$intro作为参数,传给upper调节器对应的函数,

并显示该函数值,而不是$intro

 

$标签变量本身 会当成 调节器的第1个参数自动传入,

如果需要传更多参数,在调节器后面,':'隔开更多参数.

例  {$news|truncate:7:"..."}

 

常用变量调节器

date_format [格式化日期

default [默认值

escape [编码

indent [缩进

lower [小写

nl2br [换行符替换成 <br />] 

replace [替换

strip [去除(多余空格)] 

strip_tags [去除html标签

upper [大写

动手写一个变量调节器

 

*:如何做到中文截取无乱码(常见的一道面试题)

 


Smarty模板编译的特点

Phplib也是一种模板引擎

Smarty的一个特点先编译成.php文件,再执行该 PHP

Phplib是把变量直接替换模板中的标签.

 

Smarty在第一次运行的时候,稍慢 ,包含了 编译模板+包含执行

后面的运行中速度会快,因为直接包含PHP文件.

 

: smarty什么时间重新编译模板?

根据模板修改的时候.

 

 

 

 

 

 

 

如果想强制编译比如在开发过程中

可以force_compile=true 强制编译
Display, fetch的区别

Display ftech方法第4个参数为true的调用.

Fetch4个参数为true,则把编译后文件的运行结果输出!

.......           false,则把编译后文件的运行,返回,不输出.

 

: display() = echo fetch();

 

如何实现页面静态化?

就是把.php的输出内容,保存成html

但需要考虑以下细节:

1:生成的静态页面的地址,

:253新闻如果是动态情况下,News.php?nid=253

如果生成了静态页面 253.html

不能直接放一个目录下要按规律分目录,例如 年/月日/类别/253.html

 

 

 

 

 

 

 

大批量生成静态页面,以织梦为例

新闻表

有个字段标志是否已生成静态页面 ,

另个字段记录生成后静态页面的地址

 

生成列表页面或主页时从新闻表取地址

 

注意目录的深度目录深不利于SEO,浅的话,每个目录放的页面过多.

 

 

Smarty如何获取PHP编译文件要输出的内容

:利用输出缓冲来实现

Ob_*系列函数

 


缓存

1:首选打开缓存配置项  $smarty->caching = true;

2:缓存生命周期的配置选项: $smarty->cache_lifetime = 整数秒

3:$smarty->is_cached()判断是否缓存,如果缓存,则避免IO操作

 

单模板多缓存

1个模板还可以根据其他参数,缓存多个结果,比如商品页面根据商品id来为每个商品缓存一个页面.

原则凡是能够影响到页面内容的参数,就要根据此参数影响cached_id

这样,不同参数才能对应不同的缓存内容.

 

用法:

Display(模板名[,缓存名]);

同一个模板名,如果不加缓存名,只能生成一个缓存文件.

如果有缓存名,则会按 缓存名+模板名 生成缓存文件.

如果同一个模板,提供不同的缓存名

则一个模板会产生多个缓存.

 

同理在判断某个模板是否已被缓存的时候,也需要注意,

要传一个缓存名.

即 is_cached(模板名,缓存名)  才能合理判断.

 

缓存判断原理

当前时间 缓存生成时间 生命周期 

 

 

局部缓存

在模板中,不需要缓存的地方,{insert name="nocachedid"}来表示那么该处最终的值是 insert_nocachedid()的返回值

 

 

通过hash,"局部不缓存"的数组包围起来,

用该hash,把整个缓存文件 explode拆成数组

Arrray(

'html代码'

不缓存内容,

Html代码

不缓存内容

)

 

循环该数组分析"不缓存内容",把数组分析出来,读取数组的$arr['name'],

name就是不缓存内容,而且是待调用函数的名称.

调用 insert_name(), 把函数的返回值替换掉"不缓存内容"

数组循环替换一遍之后,就把页面上所有不缓存的部分都替换成了函数的返回值,

最后,

再把数组implode拼接起来,就是最终的页面内容.

 

 

 

 


 

 

清除缓存

清除缓存就把"模板名+缓存名"对应的缓存文件删除掉

Clear_cache(模板名[,缓存名]);

 

Clear_all_cache();

 

 

 

 

 

 


Smarty定界符冲突的解决

如果smarty用定界符,比如 {,},

此定界在js,css里都有很可能碰到,如果碰到,会当成smarty标签来解析,进而引发错误发生.

 

解决方法:

1:换定界符,如 {> <}

2:literal标签,"原义","字符意义的","无夸张的"

 

 

模板的包含

include标签来包含

具体语法 {include file="xxx.html"}

注意,也可以有多级目录来放置模板如果有多级目录,

以哪一个目录来定位?

:$smarty->template_dir目录来定位
:缓存

按缓存位置分:文件缓存或者内存缓存

1:文件缓存就是把数据以文件形式保存,

这个过程,是消耗IO资源.

 

2:页面缓存或者静态页面 ,缓存的是整体html代码,有大量的冗余的缓存.

 

按缓存内容分页面缓存和数据缓存

3:真正应该缓存的是数据,而不是文件

 

例如:1500W条数据中,300W条被频繁访问,

可以把这300W条数据(不是静态页面 ),缓存到内存

甚至把300W条数据缓存到数据库'

 

4:p_w_picpaths,js,css,等文件进行 前端缓存