php twig模板引擎
1. 什么是Twig模板引擎
Twig是一个强大且灵活的PHP模板引擎,它提供了一种更简洁和可扩展的方法来创建PHP应用程序的视图层。Twig模板引擎旨在将设计与业务逻辑分离,并为开发人员提供一种更加清晰和易于维护的方式来构建网页。Twig由Symfony框架的开发团队开发,因此它与Symfony的组件非常兼容,并且被广泛用于Symfony应用程序中。
2. Twig的安装和配置
注意:PHP版本至少在 7.0.0以上
要使用Twig模板引擎,在你的PHP项目中需要先进行安装。可以使用Composer进行安装,执行以下命令:
composer require twig/twig
安装完成后,在你的PHP文件中引入Twig的自动加载文件:
require_once 'vendor/autoload.php';
2.1 phpstudy安装composer
注意:PHP版本至少在 7.0.0以上
笔者使用的是phpstudy安装twig,要先安装composer,phpstudy自带composer安装,可以自选一个版本安装
2.2 安装twig
在phpstudy中创建一个项目,就叫twig,然后右键项目,点击composer进入cmd界面
2.2.1 配置国内镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
2.2.2 更新composer
composer self-update
2.2.3 安装twig
输入安装twig命令
composer require twig/twig
看到项目中出现vendor,说明已经安装完成
3.hello world
在根目录twig下新建view文件夹,在view下新建cache和templates两个文件夹,在templates文件夹下新建一个hello.html文件,在根目录下新建入口文件index.php,文件内容如下:
hello.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h2>hello world! {{name}}</h2>
</body>
</html>
index.php
- ./view/templates :为hello.html文件所在目录
- ./view/cache : 为cache文件夹所在目录
<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, [
'cache' => './view/cache',
'debug' => true,
]);
echo $twig->render('hello.html',['name'=>'twig模板字符串']);
浏览器访问index.php,{{name}}能正常解析,说明成功运行!
4 变量
4.1 全局变量
以下变量总是在模板中可用:
- _self:引用当前的模板名称;
- _context:引用当前上下文;
- _charset:引用当前的字符集。
<h2>hello world! {{name}}</h2>
<h2>全局变量:{{_self}}</h2>
<h2>全局变量:{{_context}}</h2>
<h2>全局变量:{{_charset}}</h2>
结果:
hello world! twig模板字符串
全局变量:hello.html
全局变量:Array
全局变量:UTF-8
4.2 修改变量
您可以为代码块中的变量赋值。使用set标签:
{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}
例如:
<h2>hello world! {{name}}</h2>
<p>{% set name = '修改后的name' %}</p>
<p>{{name}}</p>
浏览器输出:
hello world! twig模板字符串
修改后的name
4.3 数组和对象变量
在根目录新建一个condition.php,内容如下:
<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, [
'cache' => './view/cache',
'debug' => true,
]);
$user = [
'id' => 1,
'name' => 'tom',
'age'=>18,
'intro' => 'my name is tom',
'now' => date_format(new DateTime(),"Y/m/d H:i:s"),
];
class tom {
public $is_login = true;
public $sex = '男';
public $name = 'tom';
}
echo $twig->render('condition.twig',['user'=>$user,'tom'=>new tom()]);
在twig/view/templates下新建一个condition.twig模板文件,内容如下:
<p>{{ user['id'] }}</p>
<p>{{ user['name'] }}</p>
<p>{{ user['age'] }}</p>
<p>{{ user.intro }}</p>
<p>{{ user['now'] }}</p>
<h1>{{ tom.sex }}</h1>
访问condition.php,浏览器输出:
1
tom
18
my name is tom
2025/01/25 18:31:15
男
5 控制结构
Twig支持各种控制结构,如条件语句和循环语句。以下是一些示例:
5.1 条件语句
使用Twig的条件语句可以根据不同的条件选择性地渲染模板的一部分。
还是以condition.twig为例
<p>{{ user['id'] }}</p>
<p>{{ user['name'] }}</p>
<p>{{ user['age'] }}</p>
<p>{{ user.intro }}</p>
<p>{{ user['now'] }}</p>
<h1>{{ tom.sex }}</h1>
{% if tom.is_login %}
<p>Welcome, {{ tom.name }}!</p>
{% else %}
<p>Please log in.</p>
{% endif %}
访问condition.php,浏览器输出:
1
tom
18
my name is tom
2025/01/25 18:39:40
男
Welcome, tom!
Twig还支持使用elseif
关键字来添加多个条件。
5.2 循环
<ul>
{% for item in user %}
<li>{{ item }} </li>
{% endfor %}
</ul>
输出:
6 过滤器
变量可以通过过滤器来修改。通过管道符号(|)将过滤器与变量分隔开,在括号中可以有可选的参数。多个过滤器可以被链式。一个过滤器的输出应用于下一个过滤器。
本例新建./view/templates/filter.twig 和 ./filter.php
filter.php
<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, [
'cache' => './view/cache',
'debug' => true,
]);
$user = [
'id' => 1,
'name' => 'tom',
'age'=>18,
'intro' => 'my name is tom',
'now' => date_format(new DateTime(),"Y/m/d H:i:s"),
];
$filter = new \Twig\TwigFilter('ff', function ($number) {
return $number . "我是过滤器";
});
$twig->addFilter($filter);
echo $twig->render('filter.twig',['user'=>$user]);
filter.twig
<p>{{ user.name }}</p>
<p>{{ user.name | ff }}</p>
其中的$number为传入的变量,即user.name
7 函数
函数的定义与过滤器完全相同,但您需要创建Twig_Function的一个实例:
可以调用函数来生成内容。函数由名称调用,后面是括号(()),可能有参数。
在filter.php中添加如下代码:
$function = new \Twig\TwigFunction('func', function ($number) {
return $number."我是函数";
});
$twig->addFunction($function);
filter.twig
<p>{{ user.name }}</p>
<p>{{ user.name | ff }}</p>
<p>{{ func(user.name)}}</p>
输出结果:
tom
tom我是过滤器
tom我是函数
8 注解(Comments)
要在模板中引用一行,请使用注释语法{ #…# }。这对于调试或为其他模板设计人员或您自己添加信息非常有用:
{# note: disabled template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}
9 包括其他模板(Including other Templates)
include函数用于包含模板,并将该模板的呈现内容返回当前的模板
新建一个./view/templates/index.html,内容如下:
{{ include('hello.html') }}
输出:
hello world! twig模板字符串
修改后的name
10 模板继承
Twig最强大的部分是模板继承。模板继承允许您构建包含站点所有常见元素的基本“骨架”模板,并定义子模板可以覆盖的块。
听起来很复杂,但是很基础。从一个例子开始就更容易理解。
我们来定义一个基模板,./view/templates/base.twig,它定义了一个简单的html框架文档:
<h1>{% block header%} 默认大标题 {% endblock %}</h1>
<h2 id="content" style="color:red;">{% block content %}默认正文{% endblock %}</h2>
<div id="footer">
<p> {% block footer %}
Copyright 2025 by 小彭爱学习
{% endblock %}
</p>
</div>
在本例中,block标记定义子模板可以填充的3个块。所有的块标记都是告诉模板引擎,子模板可以覆盖模板的那些部分。
block后面的header.content,footer为自定义的块名,后面引用时根据块名来覆盖。
新建./extend.php
<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, [
'cache' => './view/cache',
'debug' => true,
]);
echo $twig->render('base.twig');
访问extend.php,浏览器输出如下:
默认大标题
默认正文
Copyright 2025 by 小彭爱学习
新建一个./view/templates/extend.twig,继承base.twig:
{% extends "base.twig" %}
{% block header %}修改后大标题{% endblock %}
{% block content %}修改后正文{% endblock %}
修改extend.php
<?php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./view/templates');
$twig = new \Twig\Environment($loader, [
'cache' => './view/cache',
'debug' => true,
]);
echo $twig->render('extend.twig');
再次访问extend.php,浏览器输出如下:
修改后大标题
修改后正文
Copyright 2025 by 小彭爱学习
我们可以发现对应的块名内的内容被继承后的模板修改了
11 HTML转义(HTML Escaping)
当从模板生成HTML时,总是有一个风险,变量将包括影响生成HTML的字符。有两种方法:手动转义每个变量,或者默认情况下自动转义。
Twig支持这两种,自动转义是默认启用的。
自动转义策略可以通过autoescape选项和默认的html来配置。
11.1 使用手动转义
如果手动转移已启用,如果需要转义变量这是您的责任。转义什么?任何你不信任的变量。
通过escape或e过滤器将变量通过管道进行转义:
{{ user.username|e }}
默认情况下,escape过滤器使用html策略,但是根据转义上下文,您可能想要显式地使用其他可用策略:
{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}
11.2 使用自动转义
无论是否启用了自动转义,您都可以通过使用自动转义标记来标记一个模板的一个片段:
{% autoescape %}
Everything will be automatically escaped in this block (using the HTML strategy)
{% endautoescape %}
默认情况下,自动转义使用html转义策略。如果在其他上下文中输出变量,则需要使用适当的转义策略显式地转义它们:
{% autoescape 'js' %}
Everything will be automatically escaped in this block (using the JS strategy)
{% endautoescape %}
11.3 转义(Escaping)
有时需要或甚至有必要让Twig忽略它可能作为变量或块来处理的部分。例如,如果使用默认的语法,并且希望在模板中使用{ {作为原始字符串,而不是启动变量,则必须使用技巧。
最简单的方法是使用一个变量表达式输出变量分隔符({ {):
{{ '{{' }}
12 宏(Macros)
宏可以与常规编程语言中的函数相比较。它们是有用的,可以重用经常使用的HTML片段不重复自己。
{% macro 宏名(参数1,参数2,....) %}
内容
{% endmacro %}
宏可以在任何模板中定义,在使用之前需要通过import标签“导入”:
{% import 模板名 as 别名 %}
{{ 别名.宏名 }}
一个用户注册表单例子如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
div#id{
width: 100%;
}
span{
width:800px;
height:30px;
display: block;
text-align: center;
margin: auto 2px;
}
input{
width:800px;
}
div.bottom{
margin-top:10px;
}
</style>
</head>
<body>
<div>
<div id="register">
{% macro inputSpan(spanname,name, value, type,placeholder) %}
<span class="con">{{spanname}}:</span>
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" placeholder="{{ placeholder }}" />
{% endmacro %}
{% import "macro.twig" as macro1 %}
{{ macro1.inputSpan('用户帐号','uName', '',"text","设置用户名") }}
{{ macro1.inputSpan('设置密码','uPwd', '',"password","设置密码") }}
{{ macro1.inputSpan('密码确认','uPwdCom', '',"password","设置确认密码") }}
{{ macro1.inputSpan('手机号','phone', '',"text","设置手机号码") }}
{{ macro1.inputSpan('电子邮箱','email', '',"email","设置电子邮箱") }}
</div>
<div class="bottom">
<input type="submit" name="submit" value="注册并提交"/>
</div>
</div>
</body>
</html>
相当于:
<div>
<div id="register">
<span class="con">用户帐号:</span>
<input type="text" name="uName" value="" placeholder="设置用户名" />
<span class="con">设置密码:</span>
<input type="password" name="uPwd" value="" placeholder="设置密码" />
<span class="con">密码确认:</span>
<input type="password" name="uPwdCom" value="" placeholder="设置确认密码" />
<span class="con">手机号:</span>
<input type="text" name="phone" value="" placeholder="设置手机号码" />
<span class="con">电子邮箱:</span>
<input type="email" name="email" value="" placeholder="设置电子邮箱" />
</div>
<div class="bottom">
<input type="submit" name="submit" value="注册并提交"/>
</div>
</div>
确实可以简化很多重复的代码!
或者,您可以从模板从模板导入单个宏名称,通过from标签到当前名称空间,并可选地将它们别名为:
{% from 'forms.html' import input as input_field %}
<dl>
<dt>Username</dt>
<dd>{{ input_field('username') }}</dd>
<dt>Password</dt>
<dd>{{ input_field('password', '', 'password') }}</dd>
</dl>
如果在宏调用中没有提供,还可以为宏参数定义一个默认值:
{% macro input(name, value = "", type = "text", size = 20) %}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
{% endmacro %}
如果将额外的位置参数传递给宏调用,它们将以特殊的varargs变量作为值列表结束。
13 小结
以上就是twig的基础功能,twig 还有其他的功能,例如表达式、文字、数学运算、逻辑运算等,详细请参考官方文档。这里不再一一赘述。上述案例文档已经打包供大家下载学习。
下载地址:https://download.csdn.net/download/m0_53073183/90313992