1.1 Smarty简介
1.1.1 Smarty的引入
1、为了分工合作,模板页面中最好不要出现PHP的代码 2、需要将表现和内容相分离
1.1.2 Smarty介绍
1.2 自定义Smarty
1.2.1演化一:(smarty生成混编文件)
在模板中不能出现PHP界定符,标准写法如下: 1、html代码
<body>
{$title}
</body>
2、PHP代码
<?php
$title='锄禾';
require './1-demo.html';
运行结果 $title
不能解析的原因是:PHP不能识别{和} 解决: 将大括号替换成PHP的界定符 左花括号 替换 <?php echo 右花括号 替换 ;?> 代码实现:
<?php
$title='锄禾';
$str=file_get_contents('./index.html');
$str=str_replace('{','<?php echo',$str);
$str=str_replace('}',';?>',$str);
file_put_contents('./index.html.php',$str);
require './index.html.php';
运行:锄禾
1.2.2 演化二:(smarty封装)
由于每个页面都要替换定界符,所以需要将替换定界符的代码封装起来 由于封装在类中,所有访问的方法需要通过面向对象的方式来访问
1、创建Smarty.class.php
<?php
class Smarty{
private $tpl_var=array();
public function assign($k,$v){
$this->tpl_var[$k]=$v;
}
public function compile($tpl){
$com_file=$tpl.'.php';
$str=file_get_contents($tpl);
$str=str_replace('{$','<?php echo $this->tpl_var[\'',$str);
$str=str_replace('}','\'];?>',$str);
file_put_contents($com_file,$str);
require $com_file;
}
}
2、在index.php
<?php
require './Smarty.class.php';
$smarty=new Smarty();
$smarty->assign('title','锄禾');
$smarty->compile('./index.html');
运行结果
小结: 1、需要将外部的变量赋值到对象的内部 2、需要通过面向对象的方式访问
1.2.3 演化三:(有条件的生成混编文件)
混编文件存在并且是最新的就直接包含,否则就重新生成 模板文件修改时间<混编文件修改时间 =>混编文件是最新的 Smarty类中的代码编译代码如下:
class Smarty{
private $tpl_var=array();
public function assign($k,$v){
$this->tpl_var[$k]=$v;
}
public function compile($tpl){
$com_file=$tpl.'.php';
if(file_exists($com_file))
require $com_file;
else{
$str=file_get_contents($tpl);
$str=str_replace('{$','<?php echo $this->tpl_var[\'',$str);
$str=str_replace('}','\'];?>',$str);
file_put_contents($com_file,$str);
require $com_file;
}
}
}
小结: 生成混编文件的条件 1、混编不存在 2、模板修改了,模板文件修改时间>混编文件修改时间,说明模板修改过了。
1.2.4 演化四:文件分类存放
1、模板文件:templates 2、混编文件:templates_c 3、Smarty文件:smarty
Smarty.class.php代码如下:
<?php
class Smarty{
public $template_dir='./templates/';
public $templatec_dir='./templates_c';
private $tpl_var=array();
public function assign($k,$v){
$this->tpl_var[$k]=$v;
}
public function compile($tpl){
$tpl_file=$this->template_dir.$tpl;
$com_file=$this->template_dir.$tpl.'.php';
if(file_exists($com_file) && filemtime($tpl_file)<filemtime($com_file))
require $com_file;
else{
$str=file_get_contents($tpl_file);
$str=str_replace('{$','<?php echo $this->tpl_var[\'',$str);
$str=str_replace('}','\'];?>',$str);
file_put_contents($com_file,$str);
require $com_file;
}
}
}
index.php代码如下
<?php
require './Smarty/Smarty.class.php';
$smarty=new Smarty();
$smarty->template_dir='./view/';
$smarty->template_dir='./viewc/';
$smarty->assign('title','锄禾');
$smarty->compile('index.html');
1.2.5 演化五:封装编译方法
编译的方法是smarty的核心方法,核心方法一般是不可以直接调用,需要进行二次封装 smarty.class.php
class Smarty{
public $template_dir='./templates/';
public $templatec_dir='./templates_c';
private $tpl_var=array();
public function assign($k,$v){
$this->tpl_var[$k]=$v;
}
public function display($tpl){
require $this->compile($tpl);
}
private function compile($tpl){
$tpl_file=$this->template_dir.$tpl;
$com_file=$this->template_dir.$tpl.'.php';
if(file_exists($com_file) && filemtime($tpl_file)<filemtime($com_file))
return $com_file;
else{
$str=file_get_contents($tpl_file);
$str=str_replace('{$','<?php echo $this->tpl_var[\'',$str);
$str=str_replace('}','\'];?>',$str);
file_put_contents($com_file,$str);
return $com_file;
}
}
}
index.php
<?php
require './Smarty/Smarty.class.php';
$smarty=new Smarty();
$smarty->template_dir='./view/';
$smarty->templatec_dir='./viewc/';
$smarty->assign('title','锄禾');
$smarty->dispaly('index.hrml');
1.3 官方Smarty介绍
1.3.1 smarty目录结构
到 www.smarty.net 网站下载最新的smarty版本
libs目录结构(smarty核心文件)
plugins 自定义插件
sysplugins 系统的插件
Smarty.class.php Smarty核心文件
SmartyBC.class.php 兼容旧版本
需要掌握的smarty的属性和方法
public $left_delimiter ="{";
public $right_delimiter = "}";
protected $template_dir=array('./templates/');
protected $compile_dir='./templates_c';
protected $config_dir=array('./configs/');
protected $cache_dir='./cache/';
public function setTemplateDir(){}
public function setConfigDir(){}
public function setCompileDir(){}
public function setCacheDir(){}
1.3.2 smarty简单的操作
1、将libs目录结构拷贝到站点下,改名为smarty 2、创建模板目录templates 3、创建混编目录templates_c 4、在站点下创建1-demo.php
require './Smarty/Smarty.class.php';
$smarty=new Smarty();
$smarty->left_delimiter='{{';
$smarty->right_delimiter='}}';
$smarty->setTemplateDir('./view/');
$smarty->setCompileDir('./viewC/');
$smarty->display('1-demo.html');
在templates下创建demo1.html
<body>
{{$title}}
</body>
1.3.3 注释
语法:{* *}
注意:smarty注释在网页源码中看不见
思考:已知smarty的定界符是{*和*},那么它的注释是什么? 答:{** **}
1.2 变量
smarty中变量有3中,普通变量、配置变量、保留变量 1、普通变量 普通变量就是我们自己定义的变量 方法一:在PHP中定义
$smarty->assign('name','tom');
方法二:可以在模板定义
语法:{assign var='变量名' value='值'}
例如: {assign var='sex' value='男'}
简化写法:
{$sex='男'}
例题:
<?php
require './Smarty/smarty.class.php';
$smarty=new smarty();
$smarty->assign('name','tom');
$smarty->display('1-demo.html');
HTML代码
<body>
姓名:{$name}<br>
{assign var='age' value=20}
年龄:{$age}<br>
{$add='北京'}
地址:{$add}
</body>
运行结果
姓名:tom
年龄:
2、保留变量 Smarty中有一个特殊的保留变量(内置变量),类似于PHP中的所有的超全局变量、常量、时间等信息。
表达式 | 描述 |
---|
{$smarty.get.name} | 获取get提交的name的值 | {$smarty.post.name} | 获取post提交的name的值 | {$smarty.request.name} | 获取get和post提交的name的值 | {$smarty.cookies.name} | 获取cookie中的name的值 | {$smarty.session.name} | 获取session中的name的值 | {$smarty.const.name} | 获取常量name | {$smarty.server.DOCUMENT_ROOT} | 获取服务器的虚拟目录地址 | {$smarty.config.name} | 获取配置文件中的值 | {$smarty.now} | 获取时间戳 | {$smarty.ldelim} | 获取左界定 | {$smarty.rdelim} | 获取右界定 |
例题: PHP代码
<?php
require './Smarty/smarty.class.php';
$smarty=new Smarty();
define('name','常量name');
setcookie('name','常量name');
$_SESSION['name']='session的值';
$smarty->display('1-demo.html');
HTML代码
<body>
get提交:{$smarty.get.name}<br>
post提交:{$smarty.post.name}<br>
request提交:{$smarty.request.name}<br>
常量:{$smarty.const.name}<br>
cookie的值:{$smarty.session.name}<br>
时间戳:{$smarty.now}<br>
版本号:{$smarty.version}<br>
根目录:{$smarty.server.DOCUMENT_ROOT}<br>
左界定:{$smarty.ldelim}<br>
右界定:{$smarty.rdelim}<br>
</body>
运行结果
get提交:tom
post提交:
request提交:cookie的值
常量:常量name
cookie的值:cookie的值
session:session的值
时间戳:
版本号:
根目录:
左界定:{
右界定:}
3、配置文件 从配置文件中获取变量的值,配置文件默认的文件夹是configs 1、在站点下创建配置文件夹configs 2、在configs目录下创建smarty.conf文件
color=#FF0000
size=15px
3、PHP页面
<?php
require './Smarty/Smarty.class.php';
$smarty=new Smarty();
$smarty->display('1-demo.html');
4、HTML页面
{config_load file='smarty.conf'}
<style>
body{
color:{#color#};
font-size:{$smarty.config.size}
}
</style>
<body>
锄禾日当午
</body>
小结: 1、要使用配置文件中的值,首先必须引入配置文件,通过{config_load}标签引入 2、获取配置文件中的值的方法有两种 第一:{#变量名#} 第二:{$smarty.config.变量名}
多学一招:配置文件中的节
color=#FF0000
size=15px
[spring] #配置文件中的段落
color=#009900
size=20px
[winter]
color=#000000
size=5px
注意: 1、全局的一定要写在节的前面 2、配置文件中[]表示节 3、配置文件中的注释是# HTML页面
{config_load file='smarty.conf' section='winter'}
<style>
body{
color:{#color#};
font-size:{$smarty.config.size}
}
</style>
<body>
锄禾日当午
</body>
1.3 运算符
smarty中的运算符和PHP中是一样的。除此以外,smarty还支持如下运算符
运算符 | 描述 |
---|
eq | equal 相等 | neq | not equal 不等于 | gt | greater than 大于 | lt | less than 小于 | lte | less than or equal 小于等于 | gte | greate than or equal 大于等于 | is even | 是偶数 | is odd | 是奇数 | is not even | 不是偶数 | is not odd | 不是奇数 | not | 非 | mod | 求模取余 | div by | 被整除 | | | | |
1.4 判断
语法:
{if 条件}
{elseif 条件}
{else}
{/if}
例题: php代码
<?php
require './Smarty/smarty.class.php';
$smarty=new Smarty();
$smarty->dispaly('1-demo.html');
html代码
<body>
{if $smarty.get.score gte 90}
A
{elseif $smarty.get.score gte 80}
B
{else}
C
<hr>
{if $smarty.get.score is even}
是偶数
{elseif $smarty.get.score is odd}
是奇数
{/if}
</body>
1.5 数组
smarty中访问数组的方式有两种
数组[下标]
数组.下标
PHP代码
<?php
require './Smarty/smarty.class.php';
$smarty=new Smarty();
$stu=array('tom','berry');
$emp=array('name'=>'rose','sex'=>'女');
$goods=array(
array('name'=>'手机','price'=>22),
array('name'=>'钢笔','price'=>10)
);
$smarty->assign('stu',$stu);
$smarty->assign('emp',$emp);
$smarty->assign('goods',$goods);
$smarty->display('2-demo.html');
HTML代码
<body>
学生:{$stu[0]}--{$stu.1}<br>
雇员:{$emp['name']}--{$emp.sex}<br>
商品:
<ul>
<li>{$goods[0]['name']}</li>
<li>{$goods[0].price}</li>
<li>{$goods.1['name']}</li>
<li>{$goods.1.price}</li>
</ul>
</body>
运行结果
学生:tom--berry
雇员:rose-女
商品:
* 手机
* 22
* 钢笔
* 10
1.6 循环
smarty中支持的循环有:{for}、{while}、{foreach}、{section}。对于开发者来说用的最多的是{foreach}循环
1.6.1 for
语法:
{for 初始值 to 结束值 step 步长}
{/for}
例题:
<body>
{for $i=1 to 5}
{$i}:锄禾日当午<br>
{/for}
<hr>
{for $i=1 to 5 step 2}
{$i}:锄禾日当午<br>
{/for}
</body>
运行结果
1:锄禾日当午
2:锄禾日当午
3:锄禾日当午
4:锄禾日当午
5:锄禾日当午
___________________________
1:锄禾日当午
3:锄禾日当午
5:锄禾日当午
1.6.2 while循环
语法:
{while 条件}
{/while}
例题(输出5句):
<body>
{$i=1}
{while $i<=5}
{$i++}:锄禾日当午<br>
{/while}
</body>
1.6.3 foreach
既能遍历关联数组也能遍历索引数组 语法:
{foreach 数组 as $k=$v}
{foreachelse}
没有数组输出
{/foreach}
foreach的属性
@index:从0开始的索引
@iteration:从1开始的编号
@first:是否是第一个元素
@last:是否是最后一个元素
PHP代码
<?php
require './Smarty/smarty.class.php';
$smarty=new Smarty();
$smarty->assign('stu',array('first'=>'tom','second'=>'berry','third'=>'ketty','forth'=>'rose'));
$smarty->display('3-demo.html');
html代码
<table border="1" bordercolor="#000" width="780">
<tr>
<th>是否是第一个元素</th>
<th>索引</th>
<th>编号</th>
<th>键</th>
<th>值</th>
<th>是否是最后一个元素</th>
</tr>
{foreach $stu as $k=>$v}
<tr>
<td>{$v@first}</td>
<td>{$v@index}</td>
<td>{$v@iteration}</td>
<td>{$k}</td>
<td>{$v}</td>
<td>{$v@last}</td>
</tr>
{foreachelse}
没有数组输出
{/foreach}
</table>
1.6.4 section
section不支持关联数组,只能遍历索引数组 语法:
{section name=数组索引 loop=数组}
{/section}
例题 php
<?php
require './Smarty/smarty.class.php';
$smarty=new Smarty();
$smarty->assign('stu',array('tom','berry','ketty','rose'));
$smarty->display('3-demo.html');
html代码
<table border="1" bordercolor="#000" width="780">
<tr>
<th>是否是第一个元素</th>
<th>索引</th>
<th>编号</th>
<th>值</th>
<th>是否是最后一个元素</th>
</tr>
{section name=s loop=$stu}
<tr>
<td>{$smarty.section.s.first}</td>
<td>{$smarty.section.s.index}</td>
<td>{$smarty.section.s.iteration}</td>
<td>{$stu[s]}</td>
<td>{$smarty.section.s.last}</td>
</tr>
{sectionelse}
没有数组输出
{/section}
</table>
1.7 函数
函数有两种,自定义函数和内置函数 smarty的内置函数就是封装的PHP的关键字
1.8 变量修饰器
1.8.1 变量修饰器
变量修饰器的本质就是PHP函数,用来转换数据 php代码
<?php
require './Smarty/smarty.class.php';
$smarty = new Smarty();
$smarty->display('4-demo.html');
html代码
<body>
转成大写:{'abc'|upper}<br>
转成小写:{'ABC'|lower}<br>
默认值:{$add|default:'地址不详'}<br>
去除标签:{'<b>你好吗</b>'|strip_tags}<br>
实体转换:{'<b>你好吗</b>'|escape}<br>
日期:{$smarty.now|date_format:'%Y-%m-%d %H:%M:%S'}<br>
多个管道连续使用:{'<b>boy</b>'|strip_tags|upper}<br>
</body>
运行结果
注意: 1、将PHP的关键字或函数封装成标签称为函数,将PHP关键字封装成smarty关键字称为修饰器。内部的本质都是PHP函数或PHP关键字。 2、| 称为管道运算符,将前面的参数传递后面的修饰器使用
1.8.2 自定义变量修饰器
变量修饰器存放在plugins目录中 规则: 1、文件的命名规则:modifier.变量修饰器名称.php 2、文件内方法命名规则:smarty_modifier_变量修饰器名称(形参…){} 例题 1、在plugins目录中创建modifier.cal.php
function smarty_modifier_cal($num1,$num2,$num3)
{
return $num1+$num2+$num3;
}
2、在模板中调用
自定义变量修饰器:{20|cal:10:6}
20作为第一个参数传递
参数之间用冒号分隔
1.9 避免Smarty解析
smarty的定界符和css、js中的大括号产生冲突的时候,css、js中的大括号不需要被smarty解析 方法一:更换定界符 方法二:左大括号后面添加空白字符 方法三:{literal}{/literal} smarty不解析{literal}{/literal}中的内容
{literal}
<style>
body{color:red;}
</style>
{/literal}
1.10 缓存
缓存:页面缓存、空间缓存、数据缓存。smarty中的缓存就是页面缓存
1.10.1 开启缓存
$smarty->caching=true|1;//开启缓存
1.10.2 缓存的更新
方法一:删除缓存,系统会重新生成新的缓存文件 方法二:更新了模板文件,配置文件,缓存自动更新 方法三:过了缓存的生命周期,默认是3600秒 方法四:强制更新 PHP代码
<?php
require './Smarty/smarty.class.php';
$smarty = new Smarty();
$smarty->caching=true;
if(date('H')>=9)
$smarty->force_cache=true;
$smarty->display('5-demo.html');
1.10.3 缓存的生命周期
$smarty->cache_lifetime=-1 |0 |N
-1:永不过期
0:立即过期
N:有效期是N秒,默认是3600秒
PHP代码
$smarty->cache_lifetime=3;//缓存的生命周期
1.10.4 局部不缓存
局部不缓存有两种方法
1、变量不缓存 {$变量名 nocache}
2、整个块不缓存 {nocache} {/nocache}
代码
不缓存:{$smarty.now.nocache}<br>
不缓存{nocache}
{$smarty.now}<br>
{/nocache}
1.10.5 缓存分页
通过$smarty->display(模板,识别id)。通过识别id来缓存集合 PHP页面
<?php
require './Smarty/smarty.class.php';
$smarty = new Smarty();
$smarty->caching = true;
$smarty->display('6-demo.html',$_GET['pageNo']);
HTML页面
<body>
这是第{$smarty.get.pageNo}页
</body>
运行结果
1.10.6 缓存集合
每个组合都会产生缓存 PHP代码
<?php
require './Smarty/smarty.class.php';
$smarty = new Smarty();
$smarty->caching = true;
$color=$_GET['color'];
$size=$_GET['size'];
$smarty->display('6-demo.html',"$color|$size");
HTML
<body>
颜色:{$smarty.get.color}
大小:{$smarty.get.size}
</body>
运行结果
1.10.7 清除缓存
$smarty->clearCache(模板,[识别id])
$smarty->clearAllCache();
代码
<?php
require './Smarty/smarty.class.php';
$smarty = new Smarty();
$smarty->clearAllCache();
1.11 将smarty集成到项目中
1、将smarty拷贝到Lib目录下
2、实现smarty类的自动加载
private static function initAutoLoad(){
spl_autoload_register(function($class_name){
$map=array(
'Smarty' => LIB_PATH.'Smarty'.DS.'Smarty.class.php'
);
$namespace=dirname($class_name);
$class_name=basename($class_name);
...
elseif (isset($map[$class_name]))
$path=$map[$class_name];
else
$path=CONTROLLER_PATH.PLATFROM_NAME.DS.$class_name.'.class.php';
if(file_exists($path) && is_file($path))
echo $path;
require $path;
});
}
3、创建混编目录,并且定义混编目录地址
private static function initRoutes(){
...
define('__VIEW__',VIEW_PATH.$p.DS);
define('__VIEWC__',APP_PATH.'Viewc'.DS.$p.DS);
}
4、由于前后台都要启动模板,所以应该在基础控制器中实例化smarty
<?php
namespace Core;
class Controller{
protected $smarty;
public function __construct(){
$this->initSmarty();
}
private function initSmarty(){
$this->smarty=new \Smarty();
$this->smarty->setTemplateDir(__VIEW__);
$this->smarty->setCompileDir(__VIEWC__);
}
}
5、在控制器中使用smarty
class ProductsController extends BaseController{
public function listAction(){
$model=new \Model\ProductsModel();
$list=$model->select();
$this->smarty->assign('list',$list);
$this->smarty->display('products_list.html');
}
6、在模板中更改如下
{foreach $list as $rows}
<tr>
<td>{$rows['proID']}</td>
<td>{$rows['proname']}</td>
<td>{$rows['proprice']}></td>
<td><a href="index.php?p=Admin&c=Products&a=edit&proid={$rows['proID']}">修改</a></td>
<td><a href="index.php?p=Admin&c=Products&a=del&proid={$rows['proID']}" onclick="return confirm('确定要删除吗')">删除</a></td>
</tr>
{/foreach}
|