旗下导航:搜·么
当前位置:网站首页 > PHP框架 > ThinkPHP > 正文

ThinkPHP:模板引擎的详解【ThinkPHP教程】,ThinkPHP,模板引擎

作者:搜搜PHP网发布时间:2019-12-17分类:ThinkPHP浏览:60


导读:模板引擎由来初期做PHP开发WEB运用都是把PHP代码和HTML模板混在一同,模板引擎的降生主要就是为了处理后端与前端的完全星散(如今来看现实上是属于不完全星散)的问题...

模板引擎由来

初期做PHP开发WEB运用都是把PHP代码和HTML模板混在一同,模板引擎的降生主要就是为了处理后端与前端的完全星散(如今来看现实上是属于不完全星散)的问题,让开发与美工能够分工合作(虽然现实上终究模板事情大多依然是由后端开发人员完成),从而进步开发效力和便于保护。

伴随着PHP的疾速生长,模板引擎也越来越多,但大抵分为诠释型和编译型两种,现在主流的模板引擎大多数是编译型的,也就是会先把模板编译成PHP文件实行,只需模板文件自身不变化,就不须要从新编译,比方老牌的Smarty。诠释型的模板引擎每次实行的时刻都邑举行模板剖析流程,比方小强(tinybutstrong)。

ThinkPHP从一入手下手就内置了一个基于XML标签库手艺的编译型模板引擎,初期参考自Struts,而且不停在吸取新的头脑不停进化。

怎样挑选模板引擎

现在主流框架都带有模板引擎组件或许封装了模板引擎的完成,因而挑选内置的处理方案是最好之选,功用和稳定性都有保证。现在最盛行的模板引擎当属Laravel自带的Blade模板引擎,以及Symfony自带的Twig模板引擎。

经由历程装置模板引擎扩大,你能够在ThinkPHP中轻松运用包括Angular、Twig和Blade在内的模板引擎,以至完全不运用模板引擎而是直接用PHP文件作为模板。

由于近几年三大前端框架(React/Vue/Angular)的盛行,前后端星散开发逐步成为主流,因而从ThinkPHP5.0入手下手定位为API开发而设想,致使模板引擎的观点已被弱化了。ThinkPHP5.1版本的模板引擎举行过一次内部的重构,使得模板标签越发易用和靠近PHP语法。

最少关于大部分新的运用来讲,应当挑选更主流的前后端星散设想,只管减轻服务端的压力,也更轻易前后端零丁测试。你会在市面上不经意的看到采纳Vue和ThinkPHP的产物(之前几期的ThinkPHP开发者周刊曾报导过几个)。假如是保护一些老项目尤其是内容管理产物的时刻,依然可能会用到模板引擎。

鉴于这类状况,下一个版本的ThinkPHP框架将不会内置模板引擎,但有须要运用模板引擎的开发者依然能够运用官方自力出来的think-template类库,细致运用能够参考这篇文章。

背面的篇幅,我们主要来总结下ThinkPHP内置的模板引擎的运用和技能。

模板实行流程

体系内部的模板引擎挪用关联以下:

视图(View) <=> 模板驱动(Driver) <=> 模板引擎(Template)

视图和模板引擎之间增添了一个驱动层,所以能够很轻易的替代别的的模板引擎。一般我们在控制器中挪用的assign/fetch等要领实在都是挪用的think\View类的要领。固然,假如有必要,你也完全能够直接在控制器中操纵模板引擎类,只是不轻易切换别的模板引擎。

以fetch要领为例,我们看下终究的挪用历程:

think\Controller->fetch();
think\View->fetch();
think\view\driver\Think->fetch();
think\Template->fetch();

假如你挪用fetch要领的时刻没有传入要衬着的完全模板文件名,则会在第三步的时刻自动识别要衬着的模板文件。

很显然,最症结是末了一步,模板编译和实行的流程则悉数由

think\Template->fetch();

要领完成,这个环节大致又能够分红几个流程。

1、推断和读取页面衬着缓存

假如当前模板设置了页面输出缓存而且已衬着输出过,假如是则会读取缓存中的输出内容直接输出。

if (!empty($this->config['cache_id']) && $this->config['display_cache']) {
    // 读取衬着缓存
    $cacheContent = $cache->get($this->config['cache_id']);
    if (false !== $cacheContent) {
        echo $cacheContent;
        return;
    }
}

2、定位模板文件

定位现实的模板文件操纵由模板引擎类的parseTemplateFile要领完成,这个要领的逻辑实在和视图驱动类的parseTemplate要领是相似的,假如终究的模板文件不存在则会抛出一个模板文件不存在的非常。

$template = $this->parseTemplateFile($template);

3、推断编译缓存

假如当前的模板文件已编译过,会推断缓存是不是还有用,有用的话就不必反复剖析直接读取缓存的剖析内容。由checkCache要领担任完成。

if (!$this->checkCache($cacheFile)) {
    // 缓存无效 从新模板编译
    $content = file_get_contents($template);
    $this->compiler($content, $cacheFile);
}

4、模板编译并缓存

这一步骤是模板引擎最中心的环节,也是功用最庞杂的处所,由compiler要领担任完成,重如果剖析当前模板文件中的模板标签语法为PHP可实行代码,然后生成一个模板剖析缓存文件,也就是所谓的模板“编译”,个中运用了大批的正则表达式替代手艺,虽然正则剖析有肯定的机能开支,但得益于一次剖析屡次挪用的缓存道理,基本上模板剖析的机能开支不会影响现实运用的机能。

模板编译要领的症结代码是parse要领,parse要领担任对模板文件中的标签举行剖析,然后写入编译缓存文件,编译缓存默许运用的是文件缓存,支撑扩大。

5、读取编译缓存

模板编译的历程只是生成了模板编译缓存文件,并没有真正载入模板,这一步骤就是载入模板编译缓存,然后导入模板变量。完成要领能够参考think\template\driver\File类的read要领。

public function read($cacheFile, $vars = [])
{
    $this->cacheFile = $cacheFile;
    if (!empty($vars) && is_array($vars)) {
        // 模板阵列变量剖析成为自力变量
        extract($vars, EXTR_OVERWRITE);
    }
    //载入模版缓存文件
    include $this->cacheFile;
}

6、缓存页面输出

假如当前模板衬着的时刻开启了页面输出缓存,就会这一步生成页面衬着后的输出缓存。

模板编译道理

我们来了解下ThinkPHP的模板引擎的完成道理。前面提到过,ThinkPHP的模板引擎最早源于Struts的设想理念,基于XML和标签库的手艺完成。在设想模板言语的时刻运用体系牢固的标签来完成一般的变量输出功用(所以称之为一般标签),而应用XML标签库手艺完成的动态标签用于变量的控制或许前提推断输出。

一般标签的剖析是由think\Template类的parseTag要领完成的,主要完成了下面几个模板功用:

·变量输出(包括体系变量);

·函数过滤;

·变量运算;

·三元运算;

·实行函数以及输出效果;

·模板解释。

标签库采纳的是动态扩大的设想方案,采纳了相似XML的闭合/开放定义体式格局(这个实在也是现在模板引擎的一个范围地点),比方下面的这个:

// 闭合范例标签
<tagLib:tagName name="value" >
...
</tagLib:tagName>
// 开放范例标签
<tagLib:tagName name="value" />

tagLib就代表了一个标签库(类),背面的tagName标签就示意该标签库下面的某个标签(一般对应了标签库类的某个要领),背面的属性就是该标签支撑的属性定义。细致该标签的属性和功用则完全由标签库类的这个要领来决议。

能够在模板开头明白指出,当前模板运用了哪些标签库

{taglib name="html,article" /}

所以要扩大模板引擎的功用只须要经由历程扩大一个标签库类就能够了。大多数的内容管理体系都邑定义一套本身的模板二次开发标签,应用标签库功用就能够很轻易的定义一套属于本身的标签功用。

体系内置了一套标签库Cx,主要用于文件包括、前提控制、轮回输出等功用。内置标签库在运用的时刻无需引入,而且在运用的时刻能够省略标签库前缀,比方:

{foreach $list as $key=>$vo } 
    {$vo.id}:{$vo.name}
{/foreach}

这个模板语法置信PHP开发的很轻易上手,上面的标签剖析由think\template\taglib\Cx类的tagForeach要领完成,该要领的返回值是一个字符串,实在就是终究会剖析成的一段包括变量的PHP可实行代码。

到这里,模板引擎的实行历程和道理如今基本就邃晓了,剩下的就是模板标签的剖析细节,磨练的就是正则表达式的控制程度了。本文就不做深入了,有兴致的朋侪能够去看一些正则表达式的相干材料(比方这本《正则指引》,开发者周刊第14期也供应了一些在线的正则东西)。

遵照的准绳

运用模板引擎,要只管遵照几个主要的准绳。

不要在模板文件中增添任何的营业逻辑

模板的作用重如果举行模板变量的控制和输出,不要在模板文件中增添营业逻辑代码。

明白指定衬着模板

养成明白指定衬着模板的好习惯,防止当要领名发作变化,或许被别的要领挪用的时刻发作毛病。也不容易受模板定名范例的影响。

变量一致赋值

运用assign要领或许在view助手函数的时刻,一致一次传入模板变量。不要屡次赋值,以避免杂沓。

体系变量无需赋值到模板

关于体系变量(包括要求变量、$_SESSION和$_SERVER等体系变量)无需举行模板变量赋值,能够直接在模板中输出。

常见问题

这里总结一下经常会碰到的一些常见问题。

修正定界符

能够经由历程模板设置文件修正模板标签的定界符。

比方,修正一般标签定界符

'tpl_begin' => '{{', // 模板引擎一般标签入手下手标记
'tpl_end' => '}}', // 模板引擎一般标签完毕标记

标签库标签定界符

'taglib_begin' => '<{', // 标签库标签入手下手标记
'taglib_end' => '}>', // 标签库标签完毕标记

坚持原样输出

假如忧郁模板标签和JS代码发生殽杂,能够运用literal标签

{literal} Hello,{$name}! {/literal}

页面终究会直接输出

Hello,{$name}!

防止输出转义

5.1版本为了防止XSS进击,默许对模板变量的输出运用了平安转义,默许的转义函数是htmlentities,你能够经由历程变动default_filter设置转变默许的转义函数。

假如你不须要对某个模板变量输出举行转义(比方包括了HTML代码),能够运用:

{$data.content|raw}

分页输出就是一个须要输出HTML的典范例子,因而必需增添|raw。

关于模板主题

新版取消了本来的模板主题功用,由于模板主题对模板引擎来讲,实在无非是一个模板目次,完全能够依据本身的需求控制。

比方

$theme = 'blue';
$this->fetch('/' . $theme. '/user/index');

或许动态设置模板引擎的view_path参数

$this->view->config('view_path', \think\facade\App::getModulePath(). 'view/'. $theme . '/');

怎样封闭模板缓存

由因而编译型模板引擎,模板标签不能被直接实行,必需编译成PHP语法后才实行,因而不能封闭模板编译缓存,模板引擎每次实行衬着的时刻会检测模板文件是不是有变化,当模板文件的修正时候凌驾模板编译缓存的修正时候后,模板引擎会自动更新编译缓存。

但你能够强迫模板引擎每次都从新编译,只须要在设置文件中设置

'tpl_cache' => false, // 封闭模板缓存

运用PHP作为模板引擎

假如不愿望运用内置的模板引擎,直接运用PHP作为模板引擎,能够设置

'type' => 'php',

设置运用PHP作为模板引擎的话,是不会生成模板编译缓存的。

怎样运用第三方模板引擎

体系支撑扩大别的的第三方模板引擎,你只须要开发一个模板引擎驱动,现在已支撑的第三方模板引擎包括Smarty、Twig和Blade。

怎样跨模块输出模板

要衬着一个跨模块的模板文件,你须要运用

// 衬着user模块的模板文件
$this->fetch('User@order/index');

是不是支撑变量运算

能够直接在模板文件中举行变量运算而不须要在控制器中举行运算后再赋值都模板变量输出。

{$score1+$score2}
{$count++}

文件包括是不是支撑变量

include标签能够支撑传入变量,但只能运用

{include file="$file" /}

而不能运用

{include file="file_$name" /}

能够支撑模板输出替代么

支撑两个体式格局对模板举行输出替代,假如须要对模板文件的内容举行替代,能够设置:

'tpl_replace_string'  =>  [
    '__STATIC__'=>'/static',
'__JS__' => '/static/javascript',
]

假如是对模板衬着输出的内容举行替代,能够在控制器中运用视图过滤功用:

public function index()
{
    // 运用视图输出过滤
    return $this->filter(function($content){
    return str_replace("\r\n",'<br/>',$content);
    })->fetch();
}

模板继续的block是不是支撑嵌套

现在模板继续的block没法支撑嵌套功用,你应当运用别的体式格局处理。

浩瀚ThinkPHP入门教程,尽在ki4网,迎接在线进修!

本文转自:https://blog.thinkki4.cn/902998

以上就是ThinkPHP:模板引擎的详解的细致内容,更多请关注ki4网别的相干文章!

标签:ThinkPHP模板引擎