0x00 smarty简介

当使用PHP开发网站时,通常会将逻辑代码和显示代码混在一起,造成代码混乱、难以维护。而Smarty是一个PHP模板引擎,可以帮助开发者更好地将逻辑代码和显示代码分离开来,实现MVC架构(Model-View-Controller)中的视图层,使得网站代码更加清晰、可维护性更高。

0x01 简单使用

环境:PHP 5.5.38 + Smarty 3.1.47

下载完Smarty后需要里面的lib文件夹,放在网站目录(smarty)下,然后创建templates文件夹。

在Smarty模板中,{}被用来界定Smarty指令({{ }}是Smarty3的新语法),在templates文件夹中创建test.html,内容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>test</title>
</head>
<body>
hello,{$name}!
</body>
</html>

在网站目录下创建index.php,内容如下:

<?php
error_reporting(0);
require './libs/Smarty.class.php';
$smarty=new Smarty();
$name='ShawRoot';
$smarty->assign( 'name' , $name );
$smarty->display('./test.html');

访问网址得到:

hello,ShawRoot!

访问后生成templates_c文件夹,有个的混编文件,至此网站目录的tree大概如下^^:

│  index.php

├─libs
│ │ Autoloader.php
│ │ bootstrap.php
│ │ debug.tpl
│ │ Smarty.class.php
│ │ SmartyBC.class.php
│ │
│ ├─plugins
│ │ block.textformat.php
│ │ function.counter.php
│ │ function.cycle.php
│ │ ......
│ │ shared.mb_str_replace.php
│ │ shared.mb_unicode.php
│ │ variablefilter.htmlspecialchars.php
│ │
│ └─sysplugins
│ smartycompilerexception.php
│ ......
│ smarty_undefined_variable.php
│ smarty_variable.php

├─templates
│ test.html

└─templates_c
8cd7619adf4f34d178ed1fdab81eade4e15ae679_0.file.test.html.php

0x02 常用语法

关于注释

注意,smarty的注释在网页中是不显示的。

关于变量

方法一:在php文件中设置$smarty->assign( 'name' , $name );

方法二:在html文件中设置{assign var='name' value='ShawRoot'}

方法三:在html文件中设置{assign "name" "ShawRoot"}

上述三种方法调用的时候都是{$name}

关于超全局数组变量

  • $_GET['name']:{$smarty.get.name}
  • $_post['name']:{$smarty.post.name}

也适用于$_SERVER、$_Cookie、$_ENV等。

关于判断

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>test</title>
</head>
<body>
{if $name eq 'ShawRoot'}
    hello, girl !
{elseif $name eq 'EDS'}
    hello, boy !
{else}
    Welcome, who r u ?
{/if}
</body>
</html>

这边定义name变量的值为EDS就会输出hello, boy !

<?php
error_reporting(0);
require './libs/Smarty.class.php';
$smarty=new Smarty();
$name='EDS';
$smarty->assign( 'name' , $name );
$smarty->display('./test.html');

当然,一个小技巧,可以利用{if}直接执行php代码^^:

{if phpinfo()}
    hello!
{/if}

关于php

可以用{php}{/php}执行php代码,但是条件是加载SmartyBC:

<?php
error_reporting(0);
require './libs/SmartyBC.class.php';
$smarty=new SmartyBC();
$smarty->display('./test.html');

关于解析

<?php
error_reporting(0);
require './libs/SmartyBC.class.php';
$smarty=new SmartyBC();
$user['age']=22;
$smarty->assign( 'user' , $user );
$smarty->display('./test.html');

如果html文件按如下写,网页输出的是”成年人“:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>test</title>
</head>
<body>
{if $user['age'] > 18}
	<p>成年人</p>
{else}
	<p>未成年人</p>
{/if}
</body>
</html>

smarty提供了这样一个标签:{literal},它告诉smarty不要解析其中的内容,而是直接输出原始代码。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>test</title>
</head>
<body>
{literal}
{if $user['age'] > 18}
	<p>成年人</p>
{else}
	<p>未成年人</p>
{/if}
{/literal}
</body>
</html>

关于呈现模板

Smarty可以通过使用string:eval:资源从字符串中呈现模板。如果你的模板字符串经常被使用且不经常变化,那么使用string:,如果模板字符串变化频繁或者重用价值较低,那么使用eval:。

<?php
error_reporting(0);
require './libs/Smarty.class.php';
$smarty=new Smarty();
$a='hello ';
$b=$_GET['name'];
$smarty->display('string:'.$a);
$smarty->display('eval:'.$b.'!');
?>

关于输出

在PHP的Smarty模板引擎中,fetchdisplay方法都用于处理模板文件。

display方法直接输出处理后的模板内容到浏览器或其他输出设备。fetch方法则不直接输出模板内容,而是将处理后的内容作为字符串返回。这使得fetch方法返回的内容可以被赋值给一个变量、进一步处理或以其他方式使用。