当前位置: 首页 > news >正文

php twig模板引擎详细使用教程

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,浏览器输出:

1tom18my name is tom2025/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,浏览器输出:

1tom18my name is tom2025/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

<?phprequire_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>

输出结果:

tomtom我是过滤器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

相关文章:

php twig模板引擎详细使用教程

php twig模板引擎 1. 什么是Twig模板引擎 Twig是一个强大且灵活的PHP模板引擎&#xff0c;它提供了一种更简洁和可扩展的方法来创建PHP应用程序的视图层。Twig模板引擎旨在将设计与业务逻辑分离&#xff0c;并为开发人员提供一种更加清晰和易于维护的方式来构建网页。Twig由S…...

【Java设计模式-7】责任链模式:我是流水线的一员

一、责任链&#xff08;Chain of Responsibility Patten&#xff09;模式是个啥&#xff1f; 想象一下&#xff0c;你要请假。你先把请假申请交给了小组长&#xff0c;小组长一看&#xff0c;这事儿他能决定&#xff0c;就直接批了。要是小组长觉得这事儿得往上汇报&#xff0…...

Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面

目录 一、配置拦截器进行登录校验 1. 在config层设置拦截器 2. 实现LoginInterceptor拦截器 3. 创建JWT工具类 4. 在登录时创建JWT并存入Cookie 二、配置JWT依赖和环境 1. 添加JWT依赖 2. 配置JWT环境 本篇博客将为大家介绍了如何在Spring Boot应用中实现基于JWT的登录…...

【2025年数学建模美赛F题】(顶刊论文绘图)模型代码+论文

全球网络犯罪与网络安全政策的多维度分析及效能评估 摘要1 Introduction1.1 Problem Background1.2Restatement of the Problem1.3 Literature Review1.4 Our Work 2 Assumptions and Justifications数据完整性与可靠性假设&#xff1a;法律政策独立性假设&#xff1a;人口统计…...

计算机网络之链路层

本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 02 数据链路层 在网上看到其他人做了详细的笔记&#xff0c;就不再多余写了&#xff0c;直接参考着学习吧。 1 详解数据链路层-数据链路层的功能【王道计算机网络笔记】_wx63088f6683f8f的技术博客_51C…...

随笔十七、eth0单网卡绑定双ip的问题

在调试语音对讲过程中遇到过一个“奇怪”问题&#xff1a;泰山派作为一端&#xff0c;可以收到对方发来的语音&#xff0c;而对方不能收到泰山派发出的语音。 用wireshark抓包UDP发现&#xff0c;泰山派发送的地址是192.168.1.30&#xff0c;而给泰山派实际设置的静态地址是19…...

coffee销售数据集分析:基于时间趋势分析的实操练习

**文章说明&#xff1a;**对coffee销售数据集的简单分析练习&#xff08;时间趋势分析练习&#xff09;&#xff0c;主要是为了强化利用python进行数据分析的实操能力。属于个人的练习文章。 **注&#xff1a;**这是我第一次使用md格式编辑博客文章&#xff0c;排版上还是不是很…...

在 Vue 3 中,怎么管理环境变量

在 Vue 3 中&#xff0c;环境变量管理是通过 .env 文件来进行的&#xff0c;利用这些文件可以让开发者根据不同的环境&#xff08;开发、生产、测试等&#xff09;配置不同的变量。这一机制由 Vite 构建工具支持&#xff0c;它帮助开发者根据不同的环境需求做出相应配置。 1. …...

shallowRef和shallowReactive的用法以及使用场景和ref和reactive的区别

Vue3 浅层响应式 API 1. ref vs shallowRef 1.1 基本概念 ref: 深层响应式&#xff0c;会递归地将对象的所有属性转换为响应式shallowRef: 浅层响应式&#xff0c;只有 .value 的改变会触发更新&#xff0c;不会递归转换对象的属性 1.2 使用对比 // ref 示例 const deepRe…...

mantisbt添加修改用户密码

文章目录 问题当前版本安装流程创建用户修改密码老的方式探索阶段 问题 不太好改密码啊。貌似必须要域名要发邮件。公司太穷&#xff0c;看不见的东西不关心&#xff0c;只能改源码了。 当前版本 当前mantisbt版本 2.27 php版本 7.4.3 安装流程 &#xff08;下面流程不是…...

mysql 学习6 DQL语句,对数据库中的表进行 查询 操作

前期准备数据 重新create 一张表 create table emp(id int comment 编号,workno varchar(10) comment 工号,name varchar(10) comment 姓名,gender char comment 性别,ager tinyint unsigned comment 年龄,idcard char(18) comment 身份证号,workaddress varchar(10) c…...

零售业革命:改变行业的顶级物联网用例

mpro5 产品负责人Ruby Whipp表示&#xff0c;技术进步持续重塑零售业&#xff0c;其中物联网&#xff08;IoT&#xff09;正引领这一变革潮流。 研究表明&#xff0c;零售商们正在采用物联网解决方案&#xff0c;以提升运营效率并改善顾客体验。这些技术能够监控运营的各个方面…...

云计算的概念与特点:开启数字化时代的新篇章

在当今数字化时代,云计算(Cloud Computing)已经成为推动技术创新和业务转型的核心力量。无论是大型企业、中小型企业,还是个人用户,云计算都为其提供了高效、灵活和经济的解决方案。本文将深入探讨云计算的概念及其核心特点,帮助读者全面了解这一革命性技术。 © ivw…...

第二十一周:Mask R-CNN

Mask R-CNN 摘要Abstract文章信息研究动机Mask RCNNRoIPool与RoIAlign 双线性插值Mask Branch(FCN)其他细节Mask RCNN损失Mask分支预测 网络搭建创新点与不足总结 摘要 本篇博客介绍了Mask R-CNN&#xff0c;这是一种用于实例分割的模型&#xff0c;能够在目标检测的基础上实现…...

特朗普政府将开展新网络攻击

近日&#xff0c;特朗普政府已表态&#xff1a;减少物理战争&#xff0c;网络战将代替&#xff0c;以实现美国的全球优势。 特朗普也指示美国网络司令部可以在没有总统批准的情况下开展更广泛行动&#xff0c;尤其是应对一些突发事件&#xff0c;这其实成为了后续美国通过网络…...

Android Studio:视图绑定的岁月变迁(2/100)

一、博文导读 本文是基于Android Studio真实项目&#xff0c;通过解析源码了解真实应用场景&#xff0c;写文的视角和读者是同步的&#xff0c;想到看到写到&#xff0c;没有上帝视角。 前期回顾&#xff0c;本文是第二期。 private Unbinder mUnbinder; 只是声明了一个 接口…...

【已解决】黑马点评项目Redis版本替换过程的数据迁移

黑马点评项目Redis版本替换过程的数据迁移 【哭哭哭】附近商户中需要用到的GEO功能只在Redis 6.2以上版本生效 如果用的是老版本&#xff0c;美食/KTV的主页能正常返回&#xff0c;但无法显示内容 上次好不容易升到了5.0以上版本&#xff0c;现在又用不了了 Redis 6.2的windo…...

Maven运行任何命令都报错“Internal error: java.lang.ArrayIndexOutOfBoundsException”

今天遇到一个奇怪的问题&#xff0c;在maven工程下运行任何mvn命令都报“Internal error: java.lang.ArrayIndexOutOfBoundsException”错误&#xff0c;具体错误如下&#xff1a; $ mvn install [INFO] Scanning for projects... [ERROR] Internal error: java.lang.ArrayInd…...

电商平台爬虫开发技术分享:多年的实战经验总结

在当今数字化时代&#xff0c;电商平台的数据蕴含着巨大的商业价值。作为一名从事电商平台爬虫开发的工程师&#xff0c;我深知数据抓取的重要性及其技术挑战。经过多年的实践&#xff0c;我积累了一些宝贵的经验&#xff0c;愿意在这里与大家分享&#xff0c;希望能为同行们提…...

大模型训练策略与架构优化实践指南

标题&#xff1a;大模型训练策略与架构优化实践指南 文章信息摘要&#xff1a; 该分析全面探讨了大语言模型训练、架构选择、部署维护等关键环节的优化策略。在训练方面&#xff0c;强调了pre-training、mid-training和post-training的不同定位与目标&#xff1b;在架构选择上…...

DeepSeek-R1 蒸馏模型及如何用 Ollama 在本地运行DeepSeek-R1

在人工智能飞速发展的领域中&#xff0c;大型语言模型&#xff08;LLMs&#xff09;的出现可谓是一项重大变革。在这些模型里&#xff0c;DeepSeek - R1 及其蒸馏模型备受瞩目&#xff0c;它们融合了独特的能力与高可用性。今天我们一起聊一下 DeepSeek - R1 蒸馏模型究竟是什么…...

机器学习 ---逻辑回归

逻辑回归是属于机器学习里面的监督学习&#xff0c;它是以回归的思想来解决分类问题的一种非常经典的二分类分类器。由于其训练后的参数有较强的可解释性&#xff0c;在诸多领域中&#xff0c;逻辑回归通常用作 baseline 模型&#xff0c;以方便后期更好的挖掘业务相关信息或提…...

虚幻浏览器插件 UE与JS通信

温馨提示&#xff1a;本节内容需要结合插件Content下的2_Communication和Resources下的sample.html 一起阅读。 1. UE调用JS 1.1 JS脚本实现 该部分共两步: 导入jstote.js脚本实现响应函数并保存到 ue.interface 中 jsfunc 通过json对象传递参数&#xff0c;仅支持函数名小…...

KVM/ARM——基于ARM虚拟化扩展的VMM

1. 前言 ARM架构为了支持虚拟化做了些扩展&#xff0c;称为虚拟化扩展(Virtualization Extensions)。原先为VT-x创建的KVM(Linux-based Kernel Virtual Machine)适配了ARM体系结构&#xff0c;引入了KVM/ARM (the Linux ARM hypervisor)。KVM/ARM没有在hypervisor中引入复杂的…...

池化层Pooling Layer

1. 定义 池化是对特征图进行的一种压缩操作&#xff0c;通过在一个小的局部区域内进行汇总统计&#xff0c;用一个值来代表这个区域的特征信息&#xff0c;常用于卷积神经网络&#xff08;CNN&#xff09;中。 2. 作用 提取代表性信息的同时降低特征维度&#xff0c;具有平移…...

为AI聊天工具添加一个知识系统 之63 详细设计 之4:AI操作系统 之2 智能合约

本文要点 要点 AI操作系统处理的是 疑问&#xff08;信念问题&#xff09;、缺省&#xff08;逻辑问题&#xff09;和异常(不可控因素 ) 而 内核 的三大功能 &#xff08;资源分配/进程管理/任务调度&#xff09;以及外围的三类接口&#xff08; CLI、GUI和表面模型的 运行时…...

代码随想录——二叉树(二)

文章目录 前言二叉树最大深度二叉树的最小深度翻转二叉树对称二叉树完全二叉树的节点个数平衡二叉树二叉树的所有路径左叶子之和找左下角的值路径总和从中序与后序序列构造二叉树最大二叉树合并二叉树二叉搜索树中的搜索验证二叉搜索树二叉搜索树的最小绝对差二叉树中的众数二叉…...

一个基于Python+Appium的手机自动化项目~~

本项目通过PythonAppium实现了抖音手机店铺的自动化询价&#xff0c;可以直接输出excel&#xff0c;并带有详细的LOG输出。 1.excel输出效果: 2. LOG效果: 具体文件内容见GitCode&#xff1a; 项目首页 - douyingoods:一个基于Pythonappium的手机自动化项目&#xff0c;实现了…...

深入剖析SpringBoot启动机制:run()方法详尽解读

摘要 本文深入解析SpringBoot的启动机制&#xff0c;以run()方法为核心&#xff0c;逐步追踪并详细解释其关键步骤。首先探讨run()方法的工作原理&#xff0c;然后深入代码层面分析各个关键环节。文章提供刷新后钩子和启动后任务的代码示例&#xff0c;帮助读者理解SpringBoot源…...

deepseek v1手机端部署

在iPhone上部署DeepSeekR1 1. 安装快捷指令&#xff1a; 打开iPhone上的Safari浏览器&#xff0c;访问[这个链接](https://www.icloud.com/shortcuts/e0bc5445c39d45a78b90e1dc896cd010)下载快捷指令。 下载后&#xff0c;按照提示完成安装。 2. 获取并配置API Key&a…...

idea对jar包内容进行反编译

1.先安装一下这个插件java Bytecode Decompiler 2.找到这个插件的路径&#xff0c;在idea的plugins下面的lib文件夹内&#xff1a;java-decompiler.jar。下面是我自己本地的插件路径&#xff0c;以作参考&#xff1a; D:\dev\utils\idea\IntelliJ IDEA 2020.1.3\plugins\java-d…...

KMP算法原理 JAVA实现

KMP算法原理 JAVA实现 一、什么是KMP算法二、为什么需要KMP算法1. 算法背景1.1 暴力匹配过程1.2 暴力匹配的优劣 2. KMP算法的诞生3. next数组3.1 kmp算法的关键 三、求解KMP 一、什么是KMP算法 实际上KMP只是发明这个算法的三个人的英文名首字母短称&#xff0c;KMP本身无意义…...

利用Redis实现数据缓存

目录 1 为啥要缓存捏&#xff1f; 2 基本流程&#xff08;以查询商铺信息为例&#xff09; 3 实现数据库与缓存双写一致 3.1 内存淘汰 3.2 超时剔除&#xff08;半自动&#xff09; 3.3 主动更新&#xff08;手动&#xff09; 3.3.1 双写方案 3.3.2 读写穿透方案 3.3.…...

基于 RAMS 的数据驱动建模与应用实践:从理论到具体操作

基于 RAMS 的数据驱动建模与应用实践&#xff1a;从理论到具体操作 RAMS&#xff08;区域大气建模系统&#xff09;因其模块化设计、高分辨率模拟能力和广泛的应用领域&#xff0c;成为区域大气建模的强大工具。而数据驱动建模技术的崛起&#xff0c;使得 RAMS 的能力得到进一…...

计算机图形学实验练习(实验1.2-4.1AND补充实验12)

实验1.2 OpenGL与着色器编程 1.理论知识 1.1 OpenGL的含义 OpenGL是一种应用程序编程接口(Application Programming Interface,API),它是一种可以对图形硬件设备特性进行访问的软件库。OpenGL最新的4.3版本包含了超过500个不同的命令,可以用于设置所需的对象、图像和操…...

javascript-es6 (一)

作用域&#xff08;scope&#xff09; 规定了变量能够被访问的“范围”&#xff0c;离开了这个“范围”变量便不能被访问 局部作用域 函数作用域&#xff1a; 在函数内部声明的变量只能在函数内部被访问&#xff0c;外部无法直接访问 function getSum(){ //函数内部是函数作用…...

uni-app 程序打包 Android apk、安卓夜神模拟器调试运行

1、打包思路 云端打包方案&#xff08;每天免费次数限制5&#xff0c;最简单&#xff0c;可以先打包尝试一下你的程序打包后是否能用&#xff09;&#xff1a; HBuilderX 发行App-Android云打包 选择Android、使用云端证书、快速安心打包本地打包&#xff1a; HBuilderX …...

yolov11 解读简记

1 文章详细介绍了YOLOv11的架构设计&#xff0c;包括以下几个关键组件&#xff1a; C3k2块&#xff1a;这是YOLOv11引入的一种新型卷积块&#xff0c;替代了之前版本中的C2f块。C3k2块通过使用两个较小的卷积核代替一个大的卷积核&#xff0c;提高了计算效率&#xff0c;同时保…...

CommonAPI学习笔记-1

CommonAPI学习笔记-1 一. 整体结构 CommonAPI分为两层&#xff1a;核心层和绑定层&#xff0c;使用了Franca来描述服务接口的定义和部署&#xff0c;而Franca是一个用于定义和转换接口的框架&#xff08;https://franca.github.io/franca/&#xff09;。 ​ 核心层和通信中间…...

从入门到精通:RabbitMQ的深度探索与实战应用

目录 一、RabbitMQ 初相识 二、基础概念速览 &#xff08;一&#xff09;消息队列是什么 &#xff08;二&#xff09;RabbitMQ 核心组件 三、RabbitMQ 基本使用 &#xff08;一&#xff09;安装与环境搭建 &#xff08;二&#xff09;简单示例 &#xff08;三&#xff09;…...

深入理解若依RuoYi-Vue数据字典设计与实现

深入理解若依数据字典设计与实现 一、Vue2版本主要文件目录 组件目录src/components&#xff1a;数据字典组件、字典标签组件 工具目录src/utils&#xff1a;字典工具类 store目录src/store&#xff1a;字典数据 main.js&#xff1a;字典数据初始化 页面使用字典例子&#xf…...

Cursor 帮你写一个小程序

Cursor注册地址 首先下载客户端 点击链接下载 1 打开微信开发者工具创建一个小程序项目 选择TS-基础模版 官方 2 然后使用Cursor打开小程序创建的项目 3 在CHAT聊天框输入自己的需求 比如 小程序功能描述&#xff1a;吃什么助手 项目名称&#xff1a; 吃什么小程序 功能目标…...

进程控制的学习

目录 1.进程创建 1.1 fork函数 1.2 fork函数返回值 1.3 写时拷贝 1.4 fork 常规用法 1.5 fork 调用失败的原因 2. 进程终止 2.1 进程退出场景 2.2 进程常见退出方法 2.2.1 从main 返回 2.2.2 echo $&#xff1f; 查看进程退出码 2.2.2.1 我们如何得到退出码代表的含…...

一文讲解Java中的接口和抽象类

抽象类和接口有什么区别&#xff1f; 一个类只能继承一个抽象类&#xff1b;但一个类可以实现多个接口。所以我们在新建线程类的时候&#xff0c;一般推荐使用Runnable接口的方式&#xff0c;这样线程类还可以继承其他类&#xff0c;而不单单是Thread类&#xff1b;抽象类符合…...

Vue 3 30天精进之旅:Day 05 - 事件处理

引言 在前几天的学习中&#xff0c;我们探讨了Vue实例、计算属性和侦听器。这些概念为我们搭建了Vue应用的基础。今天&#xff0c;我们将专注于事件处理&#xff0c;这是交互式Web应用的核心部分。通过学习如何在Vue中处理事件&#xff0c;你将能够更好地与用户进行交互&#…...

STM32完全学习——RT-thread在STM32F407上移植

一、写在前面 关于源码的下载&#xff0c;以及在KEIL工程里面添加操作系统的源代码&#xff0c;这里就不再赘述了。需要注意的是RT-thread默认里面是会使用串口的&#xff0c;因此需要额外的进行串口的初始化&#xff0c;有些人可能会问&#xff0c;为什么不直接使用CubMAX直接…...

Shodan Dorks安装指南,通过Shodan搜索漏洞

Shodan Dorks是一种基于Shodan的工具&#xff0c;不知道Shodan是什么的不必阅读下面的内容。简单的说就是&#xff0c;利用预定义的查询&#xff08;dorks&#xff09;&#xff0c;通过Shodan轻松搜索漏洞和机密信息。 推荐渗透测试人员自行测试。 安装方法&#xff1a; 1.确…...

poi在word中打开本地文件

poi版本 5.2.0 方法1&#xff1a;使用XWPFFieldRun&#xff08;推荐&#xff09; 比如打开当前相对路径的aaaaa.docx XWPFFieldRun run paragraph.createFieldRun();CTRPr ctrPr run.getCTR().addNewRPr();CTFonts font ctrPr.addNewRFonts();// 设置字体font.setAscii(&quo…...

Linux查看服务器的内外网地址

目录&#xff1a; 1、内网地址2、外网地址3、ping时显示地址与真实不一致 1、内网地址 ifconfig2、外网地址 curl ifconfig.me3、ping时显示地址与真实不一致 原因是dns缓存导致的&#xff0c;ping这种方法也是不准确的&#xff0c;有弊端不建议使用&#xff0c;只适用于测试…...

OAuth1和OAuth2授权协议

OAuth 1 授权协议 1. 概述 OAuth1 是 OAuth 标准的第一个正式版本&#xff0c;它通过 签名和令牌 的方式&#xff0c;实现用户授权第三方访问其资源的功能。在 OAuth1 中&#xff0c;安全性依赖于签名机制&#xff0c;无需传递用户密码。 2. 核心特性 使用 签名&#xff08…...