PHP模板引擎smarty详细介绍,smarty模板引擎

作者: 韦德国际1946手机版  发布:2019-07-16

<?php
韦德国际1946手机版,/*
PHP模板引擎smarty详细介绍,smarty模板引擎。一、什么是smarty?

  mvc是付出中的一个宏伟的考虑,使得开采代码有了特别清楚的档案的次序,让代码分为了三层各施其职、无论是对代码的编纂以及早先时期的翻阅和护卫,都提供了十分大的方便人民群众。

1)、模板引擎概念

<?php
/*
一、什么是smarty?

smarty是一个使用PHP写出来的模板PHP模板引擎,它提供了逻辑与外在内容的分离,简单的讲,
目的就是要使用PHP程序员同美工分离,使用的程序员改变程序的逻辑内容不会影响到美工的页面设计,美工重新修改页面不会影响到程序的程序逻辑,这在多人合作的项目中显的尤为重要。

二、smarty优点:

1. 速度:采用smarty编写的程序可以获得最大速度的提高,这一点是相对于其它的模板引擎技术而言的。

2. 编译型:采用smarty编写的程序在运行时要编译成一个非模板技术的PHP文件,这个文件采用了PHP与HTML混合的方式,在下一次访问模板时将WEB请求直接转换到这个文件中,而不再进行模板重新编译(在源程序没有改动的情况下)

3. 缓存技术:smarty选用的一种缓存技术,它可以将用户最终看到的HTML文件缓存成一个静态的HTML页,当设定smarty的cache属性为true时,在smarty设定的cachetime期内将用户的WEB请求直接转换到这个静态的HTML文件中来,这相当于调用一个静态的HTML文件。

4. 插件技术:smarty可以自定义插件。插件实际就是一些自定义的函数。

5. 模板中可以使用if/elseif/else/endif。在模板文件使用判断语句可以非常方便的对模板进行格式重排。

三、不适合使用smarty的地方:

1. 需要实时更新的内容。例如像股票显示,它需要经常对数据进行更新,这类型的程序使用smarty会使模板处理速度变慢。

2. 小项目。小项目因为项目简单而美工与程序员兼于一人的项目,使用smarty会丧失php开发迅速的优点。


四、smarty目录结构及版本
打开smarty的官方网站,www.smarty.net/download.php。下载Smarty 3.1.12。有tar.gz和zip分别适用于linux和windows版本。

下载好后Smarty-stable-3.1.12解压缩会得到一个 Smarty-3.1.12 文件夹,里面有两个主要文件夹demo和libs

demo文件夹为示例文件夹,里面包含默认文件夹结构,是我们要进行编写程序代码的主要文件夹。demo里文件夹的名称都是smarty默认的目录结构名称,可以通过改smarty对应属性值,再把文件夹名改成我们想要的名称。
libs为smarty代码源文件夹,一般不动。

/libs/Smarty.class.php   #主文件

/libs/sysplugins/  #内部plugin

/libs /plugins/   #外部plugin,可自由扩充

/demo/cahce/   #放置缓存文件

/demo/configs /   #放置可以载入的配置文件

/demo/templates/   #放置模板文件

/demo/templates_c/    #放置对模板编译后的文件

可以把解压得到的 Smarty-3.1.12 文件夹名改成我们想要的项目名,demo也可以改成我们想要的具体存放编码的文件夹的名称

2、调试Smarty-3.1.12

创建自己的文件,在demo文件夹下创建index.php。
在templates目录中创建模板index.tpl
(几乎可以是任何文本文件的扩展名,常用的是tpl,php,html,不建议使用后两者,因为可以从浏览器直接访问而不安全。可以对apache的httpd.conf进行设置,禁止直接访问.tpl文件。或者将templats目录放在网站文档树之外。)

*/

//index.php代码
require('../libs/Smarty.class.php');
$smarty = new Smarty;
//在调用的模板里可以通过{$name}来输出name的值zhang,{}为这里的smarty分界符
$smarty->assign('name','zhang');
//调用模板tpl文件里不能执行PHP语句块
$smarty->display('templates/index.tpl');


/*
index.tpl页面内容

<html>
<body>

你好, {$name}

</body>
</html>
*/



/*
Smarty编译时的处理过程是源php文件->模板文件(可能调用多个或多次)->源php文件。。。
也就是说不影响原php文件的其他处理和输出。所以smarty模板文件可以是完整的html,也可以是其中一部分。

smarty处理过程
smarty将php源文件,首先编译成中间文件(也是php),如果启用缓存,再根据编译文件生成缓存文件(也是php),需要缓存的部分全部是硬编码。
之后的每次访问都会访问编译文件(如果编译文件已经存在),一次编译多次调用(可以是单文件的多次,也可以是多文件的多次),如果启用缓存且有缓存文件而且没有过期,则直接访问缓存文件,跳过编译文件。
编译文件一经生成,就不会被自动更新,除非模板文件或者配置文件更改。源php文件修改是不会引发重新编译的。一旦编译文件重新生成,缓存文件也必然重新生成。
*/

//Smarty允许有两种特殊的编译设置存在:
//1、 任何时候都不自动重新编译(上线阶段):只有没有该文件的编译文件时才生成,模板文件或者配置文件的更改,不会引发重新编译。
$smarty->setCompile_check(false);//默认为true,false表示任何时候都不在文件发生变更的情况下生成编译文件,除了无编译文件。
$smarty->getCompile_check();//获得当前编译检查的设置
//2、任何时候都重新编译(调试阶段):任何时候都重新编译。
$smarty->setForce_compile(true);//默认为false,true表示每次都重新编译(启用缓存的话,每次都重新缓存)
$smarty->getForce_compile();//获得当前强制编译的设置

//开启缓存
$smarty->setCaching(true);
$smarty->getCaching();//获取当前缓存状态,默认是false关闭的
$smarty->setcache_lifetime(60);//设置缓存时间单位秒
//{*模版文件*}
//{nocache}
//{$name}
//{/nocache}
//{*如果开启缓存的话放在nocache标签内的变量不会缓存,每次读取PHP源文件的值*}


/*
smarty分界符
在模板文件中,区分普通html代码和smarty代码靠的是分界符。默认是 {} ,但可能会与js和css相冲突。可以进行变更。
在3.0中模板标签将不支持空格,如{ $abc }在Smarty2中可以识别的,但是3.0里头就不行了,必须这样{$abc},这样是为了能够更好的支持javascript和css。
*/
$smarty->left_delimiter = "{";   //左分界符,2.0属性,3.0沿用
$smarty->right_delimiter = "}";
/*
分界符就相当于PHP的echo,分界符中的值都将输出,除非赋值等操作
smarty tpl文件中分界符中两个**之间的内容为注释内容如
tpl文件:
{*这是模板注释内容*}
*/


//设置缓存目录路径,不设默认"cache"
$smarty->setCacheDir("cache");
//获取缓存目录路径
$smarty->getCacheDir();

//设置配置目录路径,不设默认"configs"
$smarty->setConfigDir("configs");
//添加配置目录路径,所有路径将会以数组形式保存,调用文件时将在所有路径中查找
$smarty->addConfigDir("configs/test");
//获取配置目录路径的数组
$smarty->getConfigDir();

//设置插件目录路径,不设默认"plugins"
$smarty->setPluginsDir("plugins");
//添加插件目录路径,所有路径将会以数组形式保存,调用文件时将在所有路径中查找,plugins文件夹里放的就是可以在前台或后台按不同规则调用的函数的存储文件,文件名及函数名的命名按不同调用规则有不同写法要求
$smarty->addPluginsDir("plugins/test");
//获取插件目录路径的数组
$smarty->getPluginsDir();

//设置模板目录路径,不设默认"templates"
$smarty->setTemplateDir("templates");
//添加模板目录路径,所有路径将会以数组形式保存,调用文件时将在所有路径中查找
$smarty->addTemplateDir("templates/test");
//获取模板目录路径的数组
$smarty->getTemplateDir();

//设置编译目录路径,不设默认"templates_c"
$smarty->setCompileDir("templates_c");
//获取编译目录路径
$smarty->getCompileDir();
/*
我们可以建不同的php源文件文件夹,把编写的php文件按一定的分类放在不同的文件夹中。
然后在每个文件夹中都创建一个自定义的config文件,在config文件中创建一个新的$smarty = new Smarty 对象
然后把所有不同的文件夹的php文件的缓存,配置文件,插件,模版,编译目录都设置到同一个缓存,配置文件,插件,模版,编译目录
让该文件夹下所有PHP源文件都引用该配置文件即可获取相同配置
*/


//模版变量
$arr = array(array("zhang","li"),'a'=>array("liu","wang"),array("ming","yi"));
$smarty->assign("testArr", $arr);
//设置模版变量,为将要调用的模版提供变量,在接下来调用的模版中可以通过{$testArr}或者{$testArr['a'][0]}或者{$testArr.a.0}来访问具体某数组元素
//在模版中可以直接通过 {$testArr = "testValue" scope="global"} 来更改传过来的模板变量的值(如果不存在则在模板中创建并设置该模版变量),scope属性是标注模板变量使用范围的可不写
//在模版中更改或创建成其他数组 {$testArr = [1,2,3]}也可以{$testArr = [1,'a'=>2,2=>3]}也可以{$testArr[] = 4}或其他类似PHP中创建数组方式
//php源文件可通过 $smarty->getTemplateVars("testArr") 获取指定模版变量,如要获取模板中改变或创建的模版变量,在模板中创建或更改其值时必须加上scope属性并把值设置为scope="global"或scope="parent"

class A{
    function aa($nam){
        echo $nam;
    }
}
$smarty->assign("obj", new A);
//设置的模版变量是对象时在模版页可以如下这样调用,给模版传类对象时也是传址
//{$obj->aa('my name is y')}

//Smarty可以识别嵌入在双引号中的模版变量,只要此变量只包含数字、字母、下划线。但貌似只支持能直接转换成字符串的模版变量
$smarty->assign("testStr", "this is testStr");
//模板中可通过{"$testStr OK !"}来访问



/*
tpl模板包含模板
模板文件:
{include file="header.tpl"}
header.tpl内容:
这是顶部内容!!,欢迎你,{$name}

模板包含模板也可以是这样格式
{include file="header.tpl" testVar="这是顶部内容!!!"}
header.tpl则可以通过{$testVar}使用调用页包含时传来的模板变量
header.tpl内容:
{$testVar},欢迎你,{$name}<hr />
*/



/*
可以预先规定一系列的变量与值的对应,并放在配置文件中,在使用时载入。
配置文件默认放在configs文件夹中,可以自定义修改文件夹名。
*/

/*
#模板test.conf文件:
#键对应的值可以不用引号括起来
title = Welcome to Smarty!!
cutoff_size = 40

[china]
language = chinese

[england]
language = english

#[china],[england]为标签,未设置标签的键值为全局的只要调用该配置文件就可以在模版中使用,设置了标签的键值只有在调用配置文件时指定了对应标签才可以使用
#在PHP源文件调用配置文件语句$smarty->configLoad('test.conf', $sections = 'england');该语句下面调用的模版才可以使用该配置文件,通过$sections属性指定使用哪个标签下的键和值
#$sections参数可以不写,默认值为null,$smarty->configLoad('test.conf')则只使用全局的键值,而不能使用标签下的键值
#在模版下通过{config_load file="test.conf" section="china" scope="global"}语句调用配置文件
#section属性可以不写,默认是null,scope属性必须写{config_load file="test.conf" scope="global"}
#section属性可赋三种值
#local 只有当前模版可以使用该配置文件
#parent 只有当前模版引入该配置文件语句后包含的模版中,或在php源文件中smarty对象调用该配置文件后调用的模版中可以使用该配置文件中的键值
#global 测试效果和parent相同
#在模版中通过{#language#}来使用键值,也可以通过{$smarty.config.language}来访问配置文件键值
#PHP源文件中可以使用$smarty->getConfigVars('language')或$smarty->getConfigVariable('language')来获取键值,$smarty->getConfigVars('language')获取的还可能是数组
*/


/*
tpl文件中常用函数
tpl文件:
<!--将capture标签括起的页面显示内容存在capture指定的testCapture中 -->
<!--当达到指定条件时可通过 {$smarty.capture.testCapture} 将内容输出出来 -->
{capture name="testCapture"}
{include file="f1.tpl"}
{/capture}

{if true}
{$smarty.capture.testCapture}
{/if}



{if $name == "wang"}

Welcome wang.

{elseif $name == "zhang"}

Welcome zhang.

{else}

Welcome, whatever you are.

{/if}
{*操作符可以是 ==,>= 等也可以是 eq,ne等*}



{for $x=0; $x<count($testArr); $x  }
{$x}
{/for}
{*for循环,类似PHP代码*}


{$x=0}
{while $x<count($testArr)}
{$x  }
{/while}
{*While循环,也类似PHP代码。*}


<!--name和key属性可不写-->
{foreach name="testForeach" from=$testArr key=arId item=arVal}
{$arId}对应的值为:{$arVal}
<br>
{$smarty.foreach.testForeach.index}   <!--(循环内部使用)显示当前循环的索引,如果数组为空,返回-1-->

{$smarty.foreach.testForeach.iteration}    <!--(循环内部使用)显示当前的循环次数-->

{$smarty.foreach.testForeach.first} <!--(循环内部使用)如果为第一次循环,返回true-->

{$smarty.foreach.testForeach.last} <!--(循环内部使用)如果为最后一次循环,返回true-->

{$smarty.foreach.testForeach.total} <!-(循环内外部使用)显示循环的总次数-->
<br>
{foreachelse}  <!--$testArr数组变量没有值时(0个元素)执行。-->
$testArr is null
{/foreach}

{*也可以如下两种类PHP格式*}
{foreach $testArr as $n}
{$n}
{/foreach}

{foreach $testArr as $key=>$n}
{$key}
{/foreach}



{$sectionArr = [0=>"a",4=>"b","c","d","e",6,7,8,9,10,11,12,13,14,15,16]}
{section name="testSection" loop=$sectionArr start=0 step=4 max=6 show=true}

{$smarty.section.testSection.index}- <!--当前循环到的数组的键值-->
{$sectionArr[testSection]}- <!--当前循环到的数组的元素值-->
{$smarty.section.testSection.iteration}-<!--当前section循环的次数,从1计起-->
<br/>

{sectionelse}
$sectionArr is null
{/section}
<!--section循环适用于纯int型键值的数组-->
<!--给loop赋一个要循环的数组,start指定从数组指定键值开始循环,step指定数组下次循环的键值与本次循环键值之差,max指定循环最大次数,show指定是否循环false的话直接跳到执行sectionelse-->
<!--Section的内置变量与foreach 相同-->

*/


/*
tpl模板文件:
{literal}

<script type="text/javascript">
function a(){
    alert("this is script");
}
a();
</script>

{/literal}
{*
literal 标签区域内的数据将被当作网页html文本处理,此时模板将忽略且不分析其内部的所有字符信息。
该特性用于显示有可能包含大括号等字符信息的 js、css 。当这些信息处于 {literal}{/literal} 标签中时,模板引擎将不分析它们,而直接显示。
*}

*/

//PHP文件:
//$smarty->setDebugging(true);//对后续调用的模板进行调试。
//$smarty->getDebugging();//得到当前是否进行调试,默认false
//或在需要调试的模版中写入{debug}

/*
模板文件:

smarty3.0支持了模版继承系统,例如
f1.tpl:
<html>
<body>

{block name='top'} f1.header<br />{/block}
{block name='middle'} f1.middle<br />{/block}
{block name='buttom'} f1.buttom<br />{/block}

</body>
</html>

f2.tpl:
{extends file="f1.tpl"}
{block name='top'} f2.header<br />{/block}
{block name='other'} it can`t be show <br />{/block}
{*
如果f2.tpl中没有block标签,或f2.tpl中没有和f1.tpl中相同命名的block标签,则f2.tpl完整引入显示f1.tpl中所有内容包括block标签的内容,而f2.tpl中所有内容将忽略
如果f2.tpl中有和f1.tpl中同名block标签,则在f2.tpl显示时f2.tpl中block标签内容将覆盖f1.tpl中同名block标签的内容,在f2.tpl页面显示时,内容仍将按f1.tpl设置的格式位置显示,f2.tpl其他所有文本包括未同名的block标签及其内容都将被忽略,不显示。
block标签的内容只会覆盖父模版中同名block标签的内容,或在子模版中显示,在本页面中如果没有调用父模版或父模版中没有要覆盖的同名block标签,block标签内容在本页面中不显示
这种继承支持多文件,多重继承,意味着可以无限的继承下去
*}


{fetch file="http://www.126.com" assign="testAssign"}
{$testAssign}
{fetch file="http://www.126.com"}
{*fetch可以引用外部http,ftp的页面,如指定assign的值则把引用的内容存在指定名的变量中,否则在哪有fetch在哪显示*}
*/

//php页面:
//调用模版也可以使用此方法,在输出前做一些处理
//$output = $smarty->fetch("index.tpl");
//do something with $output here对将要输出的内容进行处理
//echo $output;//然后将模板输出

/*
模板中提交表单
<form name="input" action="file.php" method="post">
action属性可以直接写要提交到的php文件名,或者不写空action=""则提交到调用该模板的php文件中
*/


//连接数据库
mysql_connect("localhost","root","root");
mysql_select_db("test");
$smarty->assign('webDir',$_SERVER['DOCUMENT_ROOT']);//$_SERVER['DOCUMENT_ROOT']为当前项目文件夹的绝对路径
//配置JQuery的src路径最好写绝对路径或写要运行文件能找到该JQuery的相对路径因为要编译成编译文件,而编译后的文件和原路径环境不一样
?>
<script type="text/javascript" src="http://localhost/Smarty/demo/JS/jquery-1.7.2.min.js"></script>

smarty是二个运用PHP写出来的模版PHP模板引擎,它提供了逻辑与外在内容的分手,简单来讲,
指标正是要选拔PHP技术员同美术工作分离,使用的程序员退换程序的逻辑内容不会影响到油画的页面设计,美工重新修改页面不会潜濡默化到程序的程序逻辑,那在多少人合营的品种中显的一发重大。

  我们在php开拓中,视图层view是不允许有php代码来操作数据库之类的来获取数据的,我们一般都会在调控器层controller,就早就把视图层要展现的多少筹划好,方便视图层直接用来展现。

❖ 模板引擎的成效是促成逻辑与体现相分离,使程序设计者能够当心于程序作用的成本,使网页设计员范专校勘和注释于页面的宏图。也足以让网址的爱惜和立异变得更易于,创建三个尤为

 

二、smarty优点:

  smarty模板本事,能够让数据和视图举办分离,让视图中不能够直接出现php代码。那样的话,让前段页面包车型地铁支出和后台数据的付出,可以迥然差异,同一时间拓展了。

白璧无瑕的支付情况,模板引擎不属于特定本领世界,它是跨领域跨平台的定义。

1. 进程:选择smarty编写的主次能够获得最大速度的增高,那或多或少是冲突于其它的沙盘引擎才干来讲的。

  

❖ 模板引擎不只是足以让您兑今世码分离(业务逻辑代码和用户分界面代码),也足以兑现数量分离(动态数据与静态数据),还足以完结代码单元分享(代码重用),以至是多语言、动态页面与静态页面自动均衡(SDE)等等与用户分界面恐怕未有涉嫌的意义。

2. 编写翻译型:选拔smarty编写的次序在运维时要编写翻译成八个非模板本领的PHP文件,那一个文件接纳了PHP与HTML混合的措施,在下壹遍访谈模板时将WEB央求直接调换来那几个文件中,而不再进行模板重新编译(在源程序尚未改观的情状下)

  smarty模板的施用比较轻松,首要有多少个要命大旨的函数。三个是assig(),把模版中要使用的多寡实行欲赋值,二个是display(),用来深入分析和展示最终的视图模板。

2)、模板引擎分类

3. 缓存本领:smarty选择的一种缓存技巧,它能够将用户最终见到的HTML文件缓存成二个静态的HTML页,当设定smarty的cache属性为true时,在smarty设定的cachetime期内将用户的WEB诉求直接转形成那几个静态的HTML文件中来,这一定于调用三个静态的HTML文件。

  使用的大约代码如下:

❖ 模板引擎的兑现格局有数不尽,最简便易行的是“置换型”模板引擎,这类模板引擎只是将钦点模板内容(字符串)中的特定标识(子字符串)替换一下便生成了最后须求的事情数据(举个例子网页)。

  1. 插件技艺:smarty能够自定义插件。插件实际就是有的自定义的函数。
include_once "Smarty.class.php";//引入smarty类

$smarty = new Smarty;//创建smarty对象

$smarty->assign("name","zhangmiao");//赋值,以备模板中使用
$smarty->assign("age","18");

$smarty->display('index.tpl');//引入模板,展示视图页面

❖ 置换型模板引擎实现简单,但其效能底下,不大概满意高负荷的施用须求(比方有海量访谈的网址),由此还现出了“解释型”模板引擎和“编写翻译型”模板引擎等

5. 模板中得以选用if/elseif/else/endif。在模板文件使用决断语句能够十三分便利的对模板举办格式重排。

 

❖ Smarty模版引擎属于“编写翻译型”模板引擎。

三、不合乎利用smarty的地方:

我们看下模板源代码是那样的:

3)、模板引擎实现进度(自定义模板引擎)

1. 必要实时更新的剧情。举例像股票显示,它供给常常对数码实行更新,那项目标顺序选用smarty会使模板管理速度变慢。

<h1>测试模板1</h1>
我的名字是:{$name}<br/>
我的年纪是:{$age}<br/>

1.前端须求多少的地方我们用四个占位符{$data}

2. 小品种。小品种因为项目轻便而美术专门的学问与程序猿兼于一个人的体系,使用smarty会丧失php开拓飞速的帮助和益处。

浏览器页面是如此的:

2.后端把必要的数量检索到$data

四、smarty目录结构及版本
张开smarty的官方网站,www.smarty.net/download.php。下载Smarty 3.1.12。有tar.gz和zip分别适用于linux和windows版本。

韦德国际1946手机版 1

3.模板引擎难解难分。有四个效果与利益一个是从php中拿多少的效劳,别的一个必要替换的效果

下载好后斯玛特y-stable-3.1.12解压缩会得到三个 Smarty-3.1.12 文件夹,里面有四个根本文件夹demo和libs

难点:大家模板中绝非php代码,大家只用了{$name}和{$age}就能够把相应的变量给展现了出去,是如何鬼吗?

  所以模板引擎有七个大旨的法子

demo文件夹为示例文件夹,里面含有暗中认可文件夹结构,是大家要拓展编写程序代码的显要文件夹。demo里文书夹的称号都是smarty暗中认可的目录结构名称,能够透过改smarty对应属性值,再把公文夹名改成大家想要的名称。
libs为smarty代码源文件夹,一般不动。

然后,大家一看smarty编写翻译后的文本是如此的:

1  assign('赋值的变量名','值'):把您想要显示的数额分配给前端页面

/libs/Smarty.class.php   #主文件

<h1>测试模板1</h1>
我的名字是:<?php echo $this->var["name"]; ?><br/>
我的年纪是:<?php echo $this->var["age"]; ?><br/>

2 display('模板的地址'),使用正则将相应的占位符换来相应的数量,并出示替换后内容

/libs/sysplugins/  #内部plugin

原来是那样,最终照旧成为了蕴藏php代码的沙盘,然而这么些模板中把标签转成php代码的行事,大家提交了smarty模板引擎来完结的。

4)斯马特y模板引擎优点

/libs /plugins/   #外界plugin,可随心所欲扩张

 

速度:接纳smarty编写的主次能够获取最大速度的提升

/demo/cahce/   #停放慢存文件

这究竟smarty模板引擎是怎么把模版里面包车型客车非php代码的标签,转换成被最后能够深入分析实施的php代码的呢?

编写翻译型:选取Smarty编写的先后在运作时要编写翻译(组合)成叁个非模板手艺的PHP文件,使后续的调用速度更加快。

/demo/configs /   #放置能够载入的配置文件

重大思路是:替换。

缓存工夫:Smarty提供了一种可挑选使用的缓存手艺,它能够将用户最终见到HTML文件缓存成一个静态的HTML页。在smarty设定的cachetime期内将用户的WEB央浼直接转换成这几个静态的HTML文件中来,这一定于调用一个静态的HTML文件。

/demo/templates/   #停放模板文件

分成了两步:

插件技能:Smarty采取面向对象实现,能够充裕便利的定义一些插件。插件实际便是部分自定义的函数。

/demo/templates_c/    #放置对模板编写翻译后的文本

  1、用过assign函数把要分析的标签变量赋值

无敌的变现逻辑:PHP担任后台,斯马特y负责前端。

能够把解压获得的 Smarty-3.1.12 文件夹名改成大家想要的项目名,demo也足以改成大家想要的现实性存放编码的文本夹的称呼

  2、通过display函数把标签替换到对象的php变量

韦德国际1946手机版 2

本文由韦德国际1946发布于韦德国际1946手机版,转载请注明出处:PHP模板引擎smarty详细介绍,smarty模板引擎

关键词: 日记本 PHP smarty

上一篇:授权登陆,php版微信完毕登入授权的实例
下一篇:没有了