同福

PHP的模板引擎Smarty的使用技巧【20210416】

介绍

介绍

开发一个网站需要考虑几个问题,首先就是编程语言,其次就是开发框架,最后还需要考虑模板引擎。编程语言这里我们自然是PHP语言了;开发框架就是编写网站后端功能模块的基础框架,这里福哥选择的是TFPHP框架;最后的模板引擎,就是在制作用户界面所使用的处理模块,也就是MVC架构里面说的视图,这里福哥就要引出今天的主角Smarty了。

Smarty是非常有名的基于PHP语言的模板引擎,它是曾经在PHP的官网享用了smarty.php.net这个官方子域名的项目,它支持非常丰富的语法,它有编译模式可以提高效率,它有非常好的开发团队,所以福哥才会在TFPHP框架里面将Smarty作为模板引擎来使用。

安装

下载

官网地址

https://www.smarty.net/

Github地址(Smarty把下载包放到了github上面)

https://github.com/smarty-php/smarty/releases/tag/v3.1.39

最新版本3.1.39

https://github.com/smarty-php/smarty/archive/refs/tags/v3.1.39.tar.gz

安装

将源码包解压缩到自己的项目里面就可以了,因为福哥使用的是TFPHP框架,所以照例放到了旧版本的同级目录下面。

home/topic/2021/0416/14/b900296184614572063045a5e35c864b.jpg

初始化

初始化

下面是一个标准的初始化示例。

include(__DIR__. "/../../TFPHP/Extends/Template/Smarty/Smarty-3.1.39/libs/Smarty.class.php");

$smartyObj = new Smarty();

// 这是模板所在的根目录
$smartyObj->template_dir = __DIR__. "/smarty/template";
// 这是编译后的模板的根目录,最好单独设置一个目录
$smartyObj->compile_dir = __DIR__. "/smarty/compile";
// 这是缓存的根目录,最好单独设置一个目录
$smartyObj->cache_dir = __DIR__. "/smarty/cache";
// 这是制作模板的开始/结束标记,默认是 { 和 },福哥比较喜欢用asp/jsp的标记
$smartyObj->left_delimiter = "<%";
$smartyObj->right_delimiter = "%>";
// 如果开启auto_literal特性,制作模板的时候开始/结束标记于模板代码之间不能有空格,这个福哥不喜欢,关掉它
$smartyObj->auto_literal = false;

指定变量

我们可以通过assign方法将后端的程序里面的变量指定到前端模板里面给Smarty引擎调用,但是在前端模板里面不能直接访问后端程序里面的变量数据。

// 指定普通变量
$smartyObj->assign("varString", "同福");

输出

我们可以通过display方法调用指定的模板文件将用户界面显示出来。

// 输出,通过display方法调用一个制作好的模板把它编译之后显示出来
$smartyObj->display("test.tpl");

使用

福哥写了一个示例,演示如何将后端程序的变量指定给前端模板来使用的。

后端程序

下面演示如何向前端模板指定变量。

// 指定普通变量
$smartyObj->assign("varInt", 10);
$smartyObj->assign("varDouble", 1.2);
$smartyObj->assign("varString", "同福");
$smartyObj->assign("varHtml", "<h3>福哥</h3>");

// 指定数组变量
$smartyObj->assign("varArray", array(
    "id"=>35,
    "name"=>"鬼谷子叔叔",
    "link"=>"https://tongfu.net/home/35.html"
));

// 指定对象变量
class User{
    public int $id;
    public string $name;
    public string $link;
    public function __construct(int $id, string $name, string $link){
        $this->id = $id;
        $this->name = $name;
        $this->link = $link;
    }
}
$smartyObj->assign("varObject", new User(35, "鬼谷子叔叔", "https://tongfu.net/home/35.html"));

前端模板

下面是前端模板代码的示例。

<table border="1">
    <tr>
        <td>整型</td><td><% $varInt %></td>
    </tr>
    <tr>
        <td>双精</td><td><% $varDouble %></td>
    </tr>
    <tr>
        <td>字符串</td><td><% $varString %></td>
    </tr>
    <tr>
        <td>HTML</td><td><% $varHtml %></td>
    </tr>
    <tr>
        <td>数组</td><td>
            <a href="<% $varArray.link %>">(<% $varArray.id %>)<% $varArray.name %></a>
        </td>
    </tr>
    <tr>
        <td>对象</td><td>
            <a href="<% $varObject->link %>">(<% $varObject->id %>)<% $varObject->name %></a>
        </td>
    </tr>
</table>

效果

执行程序可以看到如下的页面效果。

home/topic/2021/0416/14/e165f7afad26d432bd8858ff3a9b4ed5.jpg

可以注意到第一次执行程序的时候速度稍微慢一点,后面再执行的时候就非常快了,因为Smarty的编译模式可以将解析过的模板转换成可执行的PHP程序,可以大幅度地提高运行速度。

语法

变量

  • 模板指定的变量可以是后端程序在任何位置声明的任何类型的变量。

  • 模板指定的变量不受后端程序声明变量的作用域限制,无论是全局、还是函数内、或者是对象的方法内都可以指定。

  • 模板指定变量通过assign方法完成,普通变量通过assgin方法指定后再更改是无效的,数组变量通过assign方法指定后再更改也是无效的,对象变量通过assign方法指定后再更改是可以同步到模板里面的,对象变量通过assign方法指定后在模板里面还可以调用对象的方法。

后端程序

$name = "同福";
$smartyObj->assign("varName", $name);
$name = "福哥";

$userArr = array(
    "id"=>35,
    "name"=>"鬼谷子叔叔",
    "link"=>"https://tongfu.net/home/35.html"
);
$smartyObj->assign("varUserArr", $userArr);
$userAname["name"] = "鬼谷子";

class User{
    public int $id;
    public string $name;
    public string $link;
    public function __construct(int $id, string $name, string $link){
        $this->id = $id;
        $this->name = $name;
        $this->link = $link;
    }
    public function line():string {

        return "<a href=\"". $this->link. "\">(". $this->id. ")". $this->name. "</a>";
    }
}
$user = new User(35, "鬼谷子叔叔", "https://tongfu.net/home/35.html");
$smartyObj->assign("varUser", $user);
$user->name = "鬼谷子";

前端模板

<table border="1">
    <tr>
        <td>普通变量</td><td><% $varName %></td>
    </tr>
    <tr>
        <td>数组变量</td><td><a href="<% $varUserArr.link %>">(<% $varUserArr.id %>)<% $varUserArr.name %></a></td>
    </tr>
    <tr>
        <td>对象变量</td><td><a href="<% $varUser->link %>">(<% $varUser->id %>)<% $varUser->name %></a></td>
    </tr>
    <tr>
        <td>对象变量调用方法</td><td><% $varUser->line() %></td>
    </tr>
</table>

效果

home/topic/2021/0416/15/14386751168de4a9039bd622cef9f485.jpg

遍历循环

  • 对数组变量进行遍历,就可以拿到数组的一个一个的元素。

  • 对字典变量进行遍历,就可以拿到字典的键和值。

后端程序

$smartyObj->assign("varUserArr", array(
    "id"=>35,
    "name"=>"鬼谷子叔叔",
    "link"=>"https://tongfu.net/home/35.html"
));

前端模板

<table border="1">
    <tr>
        <td>索引</td><td>Key</td><td>Item</td>
    </tr>
    <% foreach name=user key=myKey item=myItem from=$varUserArr %>
    <tr>
        <td><% $smarty.foreach.user.index %></td><td><% $myKey %></td><td><% $myItem %></td>
    </tr>
    <% /foreach %>
</table>

效果

home/topic/2021/0416/16/2ff708b9f6d36e12480f0498201fd1ec.jpg

按次循环

  • 按次循环需要知道起始数值和结束数值,对应数组循环的话需要考虑结束值是数组长度减一。

  • 数组的键可以使用变量表示。

后端程序

$smartyObj->assign("varLanguages", array(
    "PHP",
    "Python",
    "Java",
    "JavaScript",
    "C/C++",
    "Asp.net"
));

前端模板

<table border="1">
    <tr>
        <td>索引</td><td>语言</td>
    </tr>
    <% for $i=0 to 5 %>
    <tr>
        <td><% $i %></td><td><% $varLanguages.$i %></td>
    </tr>
    <% /for %>
</table>

效果

home/topic/2021/0416/16/fe1a6fd4e18bd7b30fa21628f3f51eaa.jpg

嵌套循环

  • 嵌套遍历循环需要注意key、item的别名不要冲突了。

  • 嵌套按次循环需要注意循环变量名称不要冲突了。

后端程序

$smartyObj->assign("varLanguages", array(
    array(100, "PHP"),
    array(200, "Python"),
    array(300, "Java"),
    array(60, "JavaScript"),
    array(30, "C/C++"),
    array(80, "Asp.net")
));

前端模板

<table border="1">
    <tr>
        <td>热度</td><td>语言</td>
    </tr>
    <% foreach item=myItem from=$varLanguages %>
    <tr>
        <% foreach item=myValue from=$myItem %>
        <td><% $myValue %></td>
        <% /foreach %>
    </tr>
    <% /foreach %>
</table>

效果

home/topic/2021/0416/16/ba7e7ea17cb25602b90aee2ccbd69181.jpg

判断语句

  • 判断语句同样使用“&&”和“||”表示“与”和“或”关系,使用“==”和“!=”表示相等和不相等。

  • 判断语句“else if”需要连着写成“elseif”这样,否则会报错。

后端程序

$smartyObj->assign("varLanguages", array(
    array("hot"=>100, "lang"=>"PHP"),
    array("hot"=>200, "lang"=>"Python"),
    array("hot"=>300, "lang"=>"Java"),
    array("hot"=>60, "lang"=>"JavaScript"),
    array("hot"=>30, "lang"=>"C/C++"),
    array("hot"=>80, "lang"=>"Asp.net")
));

前端模板

<table border="1">
    <tr>
        <td>热度</td><td>语言</td>
    </tr>
    <% foreach item=myItem from=$varLanguages %>
    <tr>
        <td>
            <% if $myItem.hot >= 200 %>
            <span style="color: red"><% $myItem.hot %></span>
            <% elseif $myItem.hot >= 100 %>
            <span style="color: blue"><% $myItem.hot %></span>
            <% else %>
            <span><% $myItem.hot %></span>
            <% /if %>
        </td>
        <td>
            <% $myItem.lang %>
        </td>
    </tr>
    <% /foreach %>
</table>

效果

home/topic/2021/0416/16/ddea42fff60eb106d5a4320cf4e56f88.jpg

总结

好了,今天福哥给童鞋们讲解了PHP的模板引擎Smarty的使用技巧,相信大家今后无论是使用TFPHP框架开发项目,还是在自己的项目里面使用Smarty模板引擎,都可以制作出非常漂亮的用户界面了。