啥是smarty

smarty是使用php开发的php模板引擎,使得php代码的逻辑和前端的表示层分离

smarty编写的程序相对于其他的模板引擎,可以大幅提高速度

采用smarty编写的程序在运行的时候会编译成一个非模板技术的PHP文件,这个文件是php和html代码混合的,在客户端下一次访问的时候会将web请求直接转换到这个编译后的文件中,而不会再次从模板中编译

安装smarty

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

下载之后把压缩包里的libs目录拷贝出来即可,这里我重命名为smarty

PHP smarty 基础知识学习_经验分享

创建一个SMTemplate类

在IDEA中运行这段代码即可

https://gitee.com/wochinijiamile/smartya

render的原理就是,将home和tpl拼接到一起,然后使用smarty的display方法进行渲染

smarty会根据tpl模板生成如下临时文件,这样的目的是加快访问速度,在代码不改变的情况下不再重新渲染

<?php
/* Smarty version 3.1.34-dev-7, created on 2020-06-09 15:02:06
  from 'C:\phpStudy\PHPTutorial\WWW\untitled1\views\home.tpl' */

/* @var Smarty_Internal_Template $_smarty_tpl */
if ($_smarty_tpl->_decodeProperties($_smarty_tpl, array (
  'version' => '3.1.34-dev-7',
  'unifunc' => 'content_5edfa46e2ba6a2_81509878',
  'has_nocache_code' => false,
  'file_dependency' => 
  array (
    '80b0bfa1284679c2de787eda3f9b1c2161bd6443' => 
    array (
      0 => 'C:\\phpStudy\\PHPTutorial\\WWW\\untitled1\\views\\home.tpl',
      1 => 1591714924,
      2 => 'file',
    ),
  ),
  'includes' => 
  array (
  ),
),false)) {
function content_5edfa46e2ba6a2_81509878 (Smarty_Internal_Template $_smarty_tpl) {
?><html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Home</title>
    <link rel="stylesheet" href="assets/css/master.css" type="text/css" media="screen" title="no title" charset="utf-8" />
</head>
<body>
<p>Heaaaaaaaaallo, World!</p>
</body>
</html><?php }
}
动态渲染

将home.tpl更改成这样

<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Home</title>
    <link rel="stylesheet" href="assets/css/master.css" type="text/css" media="screen" title="no title" charset="utf-8" />
</head>
<body>
<p>Hello, {$receiver}! It's {$date} today!</p>
</body>
</html>

将smtemplate.php更改为如下内容

function render($template, $data = array()){
        foreach($data as $key => $value){
            $this->_smarty->assign($key, $value);
        }
        $this->_smarty->display($template . '.tpl');
    }

将index.php更改成这样:

<?php


require_once('lib/smtemplate.php');

$data = array(
    'receiver' => 'JR',
    'date' => time(),
);
$tpl = new SMTemplate();
$tpl->render('home',$data);

可以看到我们的render方法多了一个接受属数组的参数

我们可以把模板中的receiver变量和data变量填充到$data数组中存储,然后传给render方法进行渲染

完整代码

PHP smarty 基础知识学习_经验分享_02

smarty模板引擎支持对数据进行格式化:使用方式如下:
<p>Hello, {$receiver|upper}! It's {$date|date_format:"%d %B"} today!</p>

效果如下:

PHP smarty 基础知识学习_经验分享_03

可以看到receiver变量被大写,而且日期也被格式化了

使用smarty的fetch改进我们的render

首先我们增加一个layouts目录

PHP smarty 基础知识学习_经验分享_04

里面有以下几个文件

hello.tpl和lipsum.tpl

这两个文件的内容可以使用smarty提供的fetch方法获取并赋值给一个变量

重写后的render方法

function render($template, $data = array(), $layout = 'page'){
       foreach($data as $key => $value){
           $this->_smarty->assign($key, $value);
       }
       $content = $this->_smarty->fetch($template . '.tpl');
       $this->_smarty->assign('__content', $content);
       $this->_smarty->display($layout . '.tpl');
   }

可以看到我们使用smarty的fetch方法将$template.tpl);模板中的文本内容获取出来并赋值给了$content 变量,然后下面再使用smarty的assign方法将该变量的值赋给了__content,这个变量名是我们在views\page.tpl模板中提前设置好的

<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <title>Home</title>
    <link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
</head>
<body>
<hr/>
{$__content}
<hr/>
</body>
</html>

这样我们就可以把layouts目录中的指定的tpl文件中的内容插入到page.tpl模板中预先留好的位置上。

这时候只需要在index.php中调用render方法,传入不同的参数即可:

<?php

require_once('lib/smtemplate.php');

$tpl = new SMTemplate();
$tpl->render('lipsum');

当我们传入lipsum时,就会显示出lipsum.tpl中的内容,并使用page.tpl中的模板进行修饰(css修饰+前后的hr):
PHP smarty 基础知识学习_经验分享_05

当我们传入hello时:
PHP smarty 基础知识学习_经验分享_06

以上就是自定义布局的相关介绍

创建我们自己的modifier(格式化工具)

首先创建出如下文件

untitled1\lib\smarty\plugins\modifier.weirdcase.php

注意文件名格式是固定的

modifier.weirdcase.php weirdcase是我们的php文件中的方法的全小写形式

内容如下:

<?php

//将所有的数字变成1,将所有的字母变成a
function smarty_modifier_weirdcase($string){
    $str_array = str_split($string);
    $result = '';
    $vowels = array('a', 'e', 'i', 'o', 'u');

    foreach ($str_array as $char){
        if (isalpjha($char)) $result .= 'a';
        if(isnbum($char)) $result .= '1';
    }

    return $result;
}
//判断是否为字母
function isalpjha($ch) {
    if(('a' <= $ch) && ('z' >= $ch))
    {
        return true;
    }
    if(('A' <= $ch) && ('Z' >= $ch))
    {
        return true;
    }
}
function isnbum($ch) {
    if(('0' <= $ch) && ('9' >= $ch))
    {
        return true;
    }
}

测试效果如下:

编辑untitled1\layouts\lipsum.tpl

<h1>{'Lorem Ipsusd678r23749823749823749823m'|weirdcase}</h1>
<p>
    这里是lipsum.tpl的内容
</p>

运行结果:

PHP smarty 基础知识学习_经验分享_07

可以看到达到了预期的效果

h1中的字符串按照我们的modifier.weirdcase.php定义的规则完成了转换