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

[Web 安全] PHP 反序列化漏洞 —— PHP 魔术方法

关注这个专栏的其他相关笔记:[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客

PHP 魔术方法 - 简介 - PHP 魔术方法 - 简单教程,简单编程PHP 中,以两个下划线 ( `__` ) 开头方法称之为 「 魔术方法 」 这些 「 魔术方法 」 在 [PHP](/l/yufei/php/php-basic-index.html) 中扮演这重要的角色,作为一名 PHP 开发人员,你必须知道它们,且会用它们 本专栏,我们就来看看和学习这些魔术方法,以及一些简单的使用范例 ## PHP 魔术方法一览 |方法名|说明| |:---|:---| |\__construct()类的构造函数 |\__destruct()| 类 - 简单教程,简单编程 https://twle.cn/c/yufei/phpmmethod/phpmmethod-basic-index.html

0x01:PHP 魔术方法简介

在 PHP 中,以两个下划线(__)开头的方法就被称为「 魔术方法 」。魔术方法是 PHP 中一个预定好的,在特定情况下会自动触发的行为方法。 这些魔术方法在 PHP 中扮演着重要的角色,作为一名 PHP 开发人员,我们必须要掌握并且能熟练使用它们。下面,开始本章的学习,以下是常见的 PHP 魔术方法,及其作用简介:

方法名作用解析
__construct()类的构造函数,创建对象时触发
__destruct()类的析构函数,对象被销毁时触发
__call()当调用对象的一个不存在或不可访问的方法时会自动调用
__callStatic()当调用对象或类的一个不存在或不可访问的静态方法时会自动调用
__get()调用不可访问、不存在的对象成员属性时触发
__set()在给不可访问、不存在的对象成员属性赋值时触发
__isset()当对不可访问属性调用 isset()empty() 时触发
__unset()当使用 reset() 重制一个对象不存在的或不可访问的属性时会自动调用
__invoke()把对象当作函数调用时触发
__sleep()执行 serialize() 函数前会先调用此方法。
__wakeup()执行 unserialize() 函数前会先调用此方法。
__toString()当把对象当成字符串调用时会触发此方法
__clone()使用 clone 关键字拷贝完一个对象后触发
__set_state()当使用 var_export() 将数组导出为变量时会自动调用
__autoload()尝试自动加载一个未定义的类
__debugInfo()打印输出调试信息,针对 var_dump() 函数

0x02:PHP 魔术方法 — __construct()

0x0201:方法简介

PHP 构造函数 __construct() 是对象被创建后自动调用的第一个方法。

任何类都会有一个构造函数,当我们没有显示的声明它时,系统其实已经为它创建了一个隐藏的默认的构造函数,这个默认的构造函数没有任何参数,也不会执行任何代码,等价于一个空函数。

一旦我们在类中显式的声明了一个构造函数,那么默认的构造函数就会消失,也可以说是我们创建的构造函数会覆盖掉系统默认的构造函数。

0x0202:方法作用

构造函数通常用于执行一些初始化任务,例如在创建对象时设置成员变量的初始值。

0x0203:方法声明

在类中声明一个构造函数的语法格式一般如下:

 class ClassName {function __construct([parameter list]){// 函数主体,这里面通常用于初始化对象的一些属性}}

注意:一个 PHP 类中只能有一个构造函数,因为 PHP 不允许进行函数重载!

0x0204:调用示例

下面的代码声明了一个 Dog 类,同时在该类中创建了一个构造函数,用于初始化对象的相应属性:

 <?php​class Dog {public $name; // 姓名public $age;  // 年龄​function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}}​$dog = new Dog("旺财", "10"); // 实例化一只小狗

如上,可以看到,我们只是实例化了 Dog 类,并没有主动调用类中的方法,__construct() 方法就自己调用了。

0x03:PHP 魔术方法 — __destruct()

0x0301:方法简介

__destruct() 方法会在该类的一个对象被删除时自动调用。一般情况下,该函数的触发时机为:

  1. 主动调用 unset($obj)

  2. 主动调用 $obj = NULL

  3. 程序自动结束。

0x0302:方法作用

__destruct() 函数通常被用于对象执行完毕后进行释放资源的操作,比如关闭文件、关闭数据库链接、清空一个结果集等。

0x0303:方法声明

在类中声明 __destruct() 函数的语法格式如下,该函数没有任何参数也没有任何返回值:

 class ClassName {function __destruct() {// 其他代码}}

0x0304:调用示例

在下面这个例子中,我们给 Dog 类添加上析构函数 __destruct(),当对象走向消亡(生命周期结束)时,它会进行提示:

 <?php​class Dog {public $name; // 姓名public $age;  // 年龄​function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}​function __destruct() {echo "=============== destruct ===============\n";echo "快乐的时光总是短暂的,你的 🐕 " . $this -> name . "还是走向了它的终点\n";echo "请不要伤心,它的故事只是已另一种形式展开。。。。。";}}​$dog = new Dog("旺财", "10"); // 实例化一只小狗

0x04:PHP 魔术方法 — __call()

0x0401:方法简介

__call() 方法只能被用于类中,当程序尝试调用类对象的一个 不存在 的或者 不可访问 的方法或属性时会被自动调用。

0x0402:方法声明

该方法有两个参数,第一个参数是调用的那个不存在的 方法名,第二个参数是一个数组(array),是传递给不存在方法的所有参数组成的数组:

 class ClassName {function __call( string $func_name, array $args) {// 内部代码}}

0x0403:调用示例

如下,我们给 Dog 类创建了一个 __call 方法,用于在程序调用其中不存在的方法时进行自动调用:

 <?php​class Dog {public $name; // 姓名public $age;  // 年龄​function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}​function __call($func_name, $args) {echo "================ Call Error ! ================\n";echo "Sorry, " . $this -> name . "不会" .$func_name . "\n";print_r($args);}}​$dog = new Dog("旺财", "1"); // 实例化一只小狗$dog -> fly("高高", $hight="100 米"); // 让小狗飞高高,想飞 100 米那么高

0x05:PHP 魔术方法 — __callStatic()

0x0501:方法简介

__callStatic() 会在程序调用一个不存在的静态方法(该方法不存在或者不可访问)时被自动调用。

0x0502:方法声明

该方法接收两个参数,第一个参数是调用的那个不存在的静态方法名,第二个参数是一个数组(array),是传递给不存在的静态方法的所有参数组成的数组:

 class ClassName {static function __callStatic( string $func_name, array $args) {// 内部代码}}

0x0503:调用示例

如下,我们给 Dog 类创建了一个 __callStatic 方法,用于在程序调用其中不存在的静态类时自动触发:

 <?php​class Dog {public $name; // 姓名public $age;  // 年龄​function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}​static function __callStatic($name, $arguments) {echo "================ Call Error ! ================\n";echo "静态方法:" . $name . "不存在!\n";print_r($arguments);}}​$dog = new Dog("旺财", "1"); // 实例化一只小狗​// 下面就是调用静态方法的写法$dog::fly("高高", $hight="100 米"); // 让小狗飞高高,想飞 100 米那么高

0x06:PHP 魔术方法 — __get()

0x0601:方法简介

当一个类定义了一个 __get() 魔术方法后,我们就可以获取该类的实例的私有属性或不存在的属性而不犯错,这里所说的获取,是指获取其值。

0x0602:方法声明

该方法的原型如下:

class ClassName {public mixed function __get( string $propertyName ) {// 内部代码}
}

0x0603:调用示例

在下面的示例中,我们创建了一个 Dog 类,并为其添加了 __get() 魔法方法,当程序调用类中不存在的属性时,就会提示报错:

<?phpclass Dog {public $name; // 姓名public $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}public function __get($propertyName) {echo "================ Get Error ! ================\n";echo "Sorry, The Dog Class Didn't have <" . $propertyName . "> attribute\n";}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗
echo $dog -> type; // 想要知道 Dog 属于哪类

0x07:PHP 魔术方法 — __set()

0x0701:方法简介

魔术方法 __set() 可以用来给类的实例的不存在的属性或不可访问的属性赋值。

0x0702:方法声明

该方法有两个参数,第一个参数 $property 是不存在的或不可访问的实例属性,第二个参数 $value 是实际要赋的值。

该方法可以有返回值,也可以没有返回值,这取决于开发者的要求:

class ClassName {public function __set( $propertyName, $value ) {// 内部代码}
}

0x0703:调用示例

在如下示例中,当我们为私有属性 age 赋值时就会触发类中的 __set 方法,做一个简单的判断,不让这个年龄过大或者过小:

<?phpclass Dog {public $name; // 姓名private $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}public function __set($propertyName, $value) {print_r("===================== Set =====================\n");if ($propertyName == "age") {if ($value < 0 or $value > 35) {echo "Error! Your Dog Age IS Error !!!\n"; // 当设置的年龄超过了狗年龄的范围时触发} else {$this -> age = $value;echo "Now, Your Dog Age is " . $this -> age . "\n";}}}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗
$dog -> age = 100; // 想让狗的年龄变成 100 岁
$dog -> age = 18;  // 想让狗的年龄回到 18 岁

0x08:PHP 魔术方法 — __isset()

0x0801:方法简介

在讨论 __isset() 魔术方法之前,笔者先简单介绍一下 isset() 方法,该方法主要用于判断一个变量或一个实例的一个属性是否被定义。

如果变量或实例的属性不存在,或被赋值为 NULL,就会返回 false,其它情况下一律返回 true,哪怕目标被赋值为 false0''

isset() 通常用于判断某个变量是否被设置,但它同时可以在外部实例中判断实例的某个属性值是否被设置,这通常有两个常见:

  1. 如果属性是公开(public)属性,那么可以直接使用 isset()来判断该属性是否设置。

  2. 如果属性是一个私有(private)的属性,那么 isset() 就无法正常工作了。

针对上述的第二种情况,我们就需要用到 __isset() 方法了。

0x0802:方法作用

通过在类中定义 __isset() 魔术方法,我们就可以使用 isset() 来判断这个类的实例的某个私有属性是否被 “设置”(只要 __isset() 返回 true,那么 isset() 方法就会返回 true,反之亦然)。

0x0803:方法声明

该方法只接收一个参数,就是要进行判断的属性名,该方法的返回值为一个 Bool 类型:

class ClassName {public bool function __isset( $propertyName ) {// 内部代码return [true or false];}
}

0x0804:调用示例

在下面的代码中,类中的 age 属性为私有的,要想判断实例的 age 属性是否被设置,我们就要借助 __isset() 方法:

<?phpclass Dog {public $name; // 姓名private $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}public function __isset($property) {print_r("WUHU, {$property} is a private attribute, __isset function is auto runs!!!\n");return isset($this -> $property);}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗
var_dump(isset($dog -> age));

0x09:PHP 魔术方法 — __unset()

0x0901:方法简介

如果一个类中定义了魔术方法 __unset(),那么我们就可以使用 unset() 函数来销毁类的私有属性,或在销毁一个不存在的属性时得到通知。

然而实际上到底有没有销毁那个属性,取决于 __unset() 的具体实现,假如我们定义了一个空的 __unset() 方法,emmmm,没人这么闲吧。

0x0902:方法声明

该方法的原型如下:

class ClassName {public function __unset( $propertyName ) {// 内部代码}
}

0x0903:调用示例

在下面的示例中,我们在 Dog 类中定义了一个 __unset() 方法,并用它尝试销毁类中的一个私有属性,与一个不存在的属性:

<?phpclass Dog {public $name; // 姓名private $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}public function __unset( $property ) {if ($property != "age") {echo "啊哦, 你销毁的东东不存在 !!!!\n";} else {echo "<$property> 已成功被销毁 !!!\n";unset($this -> $property);}}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗
unset($dog -> type); // 尝试销毁不存在的 Type 属性
unset($dog -> age);  // 尝试销毁类的私有属性 age

0x10:PHP 魔术方法 — __sleep()

0x1001:方法简介

当我们在 PHP 中调用 serialize() 函数尝试序列化一个实例时,会首先检查该实例中是否存在 __sleep() 方法,如果该方法存在,则自动调用,否则使用默认的序列化方式。

0x1003:方法声明

我们可以在 __sleep() 方法中定制类的实例的序列化输出结果,并剔除一些不需要被序列化的属性,比如那些保存了超大数据的属性。

该魔术方法没有任何参数,单必须要有返回值,返回值的类型是 Array 类的,它包含了想要序列化的该实例的属性名:

class ClassName {public array function __sleep() {// 内部代码return array();}
}

0x1004:调用示例

比如下面这个例子,我们创建了一个 Dog 类,当程序序列化该类对象时,我们剔除了 $age 属性,并对 $name 属性进行了编码操作:

<?phpclass Dog {public $name; // 姓名private $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}function __sleep() {print_r("============= Dog 类正在序列化 Ing =============");$this -> name = base64_encode($this -> name);$this -> type = "Dog"; // 临时创建一个属性return array("name", "type"); // 返回的时候排除了 $age 属性}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗
echo serialize($dog); // 对 dog 进行序列化

0x11:PHP 魔术方法 — __wakeup()

0x1101:方法简介

当我们在 PHP 中使用 unserialize() 反序列化一个对象时,如果类中存在 __wakeup() 方法,那么该方法就会被自动调用。

0x1102:方法声明

该魔术方法既没有参数,也没有返回值:

class ClassName {public function __wakeup() {// 内部代码}
}

0x1103:调用示例

下面示例中,我们往 Dog 类中添加了反序列化方法,用来在反序列化时,对 $name 进行 Base64 解码:

<?phpclass Dog {public $name; // 姓名private $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}function __sleep() {print_r("============= Dog 类正在序列化 Ing =============");$this -> name = base64_encode($this -> name);$this -> type = "Dog"; // 临时创建一个属性return array("name", "type"); // 返回的时候排除了 $age 属性}function __wakeup() {print_r("============= Dog 类正在反序列化 Ing =============");$this -> name = base64_decode($this -> name); // 对 Dog 名称进行 Base64 解码}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗$serialize_dog = serialize($dog); // 对 dog 进行序列化
echo $serialize_dog . "\n";$new_dog = unserialize($serialize_dog);
echo "\nDog 的名称: " . $new_dog -> name;

0x12:PHP 魔术方法 — __toString()

0x1201:方法简介

当我们使用 echo 语句尝试输出一个对象时,就会自动检查一个对象有没有定义 __toString() 方法,如果定义了,就会输出 __toString() 方法的返回值,如果没有定义,那么就会直接抛出一个异常,表明该对象不能直接转换为字符串。

0x1202:方法声明

该方法没有任何参数,也不会传递任何参数,但该方法必须有一个返回值,且返回值必须为字符串类型:

class ClassName {public string function __toString() {// 内部代码}
}

0x1203:调用示例

在下面例子中,我们为 Dog 类新增添了一个 __toString() 方法,并通过 echo 输出了该类:

<?phpclass Dog {public $name; // 姓名private $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}public function __toString() {return sprintf("Dog('%s', '%s')", $this -> name, $this -> age);}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗
echo $dog;

0x13:PHP 魔术方法 — __invoke()

0x1301:方法简介

当我们尝试将一个对象当作一个方法来使用时就会自动调用它的 __invoke() 方法,如果目标对象中不包含该方法,就会直接报错。

0x1302:方法声明

该方法可以有返回值,也可以没有,对于返回值的类型,它也没有任何限制:

class ClassName {public mixed function __invoke() {// 内部代码}
}

0x1303:调用示例

下面的代码,我们给 Dog 类加上了 __invoke() 魔术方法,然后我们就可以将它的实例当作普通方法来调用了:

<?phpclass Dog {public $name; // 姓名private $age;  // 年龄function __construct($name, $age) {echo "恭喜你,你成功创建了一只 🐕 !!!\n";$this -> name = $name; // 初始化 Dog 的名称echo "Dog Name : " . $this -> name . "\n";$this -> age = $age;   // 初始化 Dog 的年龄echo "Dog Age  : " . $this -> age . "\n";}function __invoke() {echo "Hello, My Name is " . $this -> name . " I am " .$this ->age . "Years Old Now !!!";}
}$dog = new Dog("旺财", "1"); // 实例化一只小狗
$dog(); // 把 dog 对象当作方法调用

相关文章:

[Web 安全] PHP 反序列化漏洞 —— PHP 魔术方法

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 PHP 魔术方法 - 简介 - PHP 魔术方法 - 简单教程&#xff0c;简单编程PHP 中&#xff0c;以两个下划线 ( __ ) 开头方法称之为 「 魔术方法 」 这些 「 魔术方法 」 在 [PHP](/l/yufei/php…...

聆听PostgreSQL数据库的使用

参考&#xff1a;&#xff08;1&#xff09;零基础入门PostgreSQL教程 &#xff08;2&#xff09;菜鸟教程 文章目录 一、PostgreSQL是什么&#xff1f;二、基本使用1.下载2.操作&#xff08;1&#xff09;数据库&#xff08;2&#xff09;表 一、PostgreSQL是什么&#xff1f;…...

2025嵌入式软件开发工程师--音频方向

一、选择题&#xff08;每题3分&#xff0c;共30分&#xff09; 1.以下哪个不是C语言中的关键字?&#xff08; &#xff09; A. int B. Float C. Define D. Return 2.以下代码的输出是: &#xff08; &#xff09; inta 5, b 10; printf("%d“, a b); A. 15 B.16 …...

C#释放内存空间的方法

目录 前言释放 C# 对象内存的六种方法1、手动释放内存空间2、使用 Using 语句3、使用 垃圾回收器4、GC.Collect() 方法5、GC.WaitForPendingFinalizers() 方法6、WeakReference 类 注意 前言 当不再需要对象时释放内存空间对于防止内存泄漏和提高应用程序性能至关重要。C# 提供…...

《鸢尾花数学大系:从加减乘除到机器学习》开源资源

《鸢尾花数学大系&#xff1a;从加减乘除到机器学习》开源资源 Gitee&#xff1a;https://gitee.com/higkoo/ bilibili&#xff1a;https://space.bilibili.com/513194466 GitHub&#xff1a;https://github.com/Visualize-ML...

如何将一台服务器的pip环境迁移到另一个机器?

在没有网络的情况下,将一台服务器的 pip 环境迁移到另一台机器,可按以下步骤进行操作: 步骤一:在源服务器上导出已安装的包列表 在有网络且已安装所需 Python 包的源服务器上,使用以下命令导出已安装的 Python 包列表: pip freeze > requirements.txt该命令会将当前…...

Java 入门 (超级详细)

一、什么是Java Java是一种高级编程语言&#xff0c;由Sun Microsystems公司于1995年推出。Java具有跨平台性、面向对象、健壮性、安全性、可移植性等特点&#xff0c;被广泛应用于企业级应用开发、移动应用开发、大数据处理、云计算等领域。Java程序可以在不同的操作系统上运…...

计算机基础面试(数据结构)

1. 数组和链表的区别是什么&#xff1f;各自的优缺点是什么&#xff1f; 专业解答&#xff1a; 数组内存连续&#xff0c;支持随机访问&#xff0c;但插入删除效率低&#xff1b;链表内存离散&#xff0c;插入删除高效&#xff0c;但访问需遍历。 初中生版&#xff1a; 数组像…...

DBGPT安装部署使用

简介 DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。 目的是构建大模型领域的基础设施&#xff0c;通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Mul…...

【蓝桥杯单片机】第十二届省赛

一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 由Y5C控制 2.编写LED函数&#xff08;led.c&#xff09; void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器…...

开源嵌入式实时操作系统NuttX介绍

一、NuttX RTOS的发展历程&#xff1a;从个人项目到Apache顶级开源项目 NuttX 是一款轻量级、可扩展的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;其发展历程堪称开源社区的经典案例。 起源与初创&#xff08;2003-2007&#xff09; NuttX 由 Gregory Nutt 于2003…...

阿里云服务器部署项目笔记 实操 centos7.9

阿里云服务器部署项目笔记 实操 centos7.9 springboot vue elementUImysqlredis 相关的redis,mysql,nginx镜像,jdk 通过网盘分享的文件&#xff1a;docker镜像 链接: https://pan.baidu.com/s/15VwcWBP4Jy07xADuvylgQw?pwdm2g9 提取码: m2g9 配置环境 连接云服务器 安装…...

Java-实现PDF合同模板填写内容并导出PDF文件

可用于公司用户合同导出pdf文件 效果图 一、导入所需要jar包 <!--生成PDF--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.11</version></dependency><dependency&…...

Docker安装Grafana数据可视化平台

介绍 Grafana是一个开源的监控和数据可视化平台&#xff0c;主要用于展示和分析时间序列数据。提供功能强大且灵活的数据可视化和监控工具&#xff0c;适用于多种场景&#xff0c;它广泛应用于DevOps、IT运维、物联网&#xff08;IoT&#xff09;和业务分析等领域。 Grafana的主…...

MyBatis-Plus 自动填充功能

MyBatis-Plus&#xff08;MP&#xff09; 提供了一个非常强大的功能——自动填充功能。该功能可以在执行插入或更新操作时&#xff0c;自动为某些字段赋值&#xff0c;免去手动设置这些字段的麻烦。常见的应用场景包括 创建时间 和 更新时间 字段的自动填充&#xff0c;帮助开发…...

解决redis lettuce连接池经常出现连接拒绝(Connection refused)问题

一.软件环境 windows10、11系统、springboot2.x、redis 6 7 linux&#xff08;centos&#xff09;系统没有出现这问题&#xff0c;如果你是linux系统碰到的&#xff0c;本文也有一定大参考价值。 根本思路就是&#xff1a;tcp/ip连接的保活(keepalive)。 二.问题描述 在spr…...

武汉大学生命科学学院与谱度众合(武汉)生命科技有限公司举行校企联培座谈会

2025年2月21日下午&#xff0c;武汉大学生命科学学院与谱度众合&#xff08;武汉&#xff09;生命科技有限公司&#xff08;以下简称“谱度众合”&#xff09;在学院学术厅举行校企联培专业学位研究生合作交流会。武汉大学生命科学学院副院长刘星教授、生命科学学院周宇教授、产…...

4.网络技术与应用

一、计算机网络基础 1. 网络基本原理 通信模型&#xff1a; OSI七层模型&#xff1a; 物理层&#xff08;传输比特流&#xff0c;如网线、光纤&#xff09;数据链路层&#xff08;MAC地址&#xff0c;交换机&#xff09;网络层&#xff08;IP地址&#xff0c;路由器&#xff0…...

Kafka 主题 retention.ms 配置修改及深度问题排查指南

文章目录 Kafka 主题 retention.ms 配置修改及深度问题排查指南版本背景查看 Kafka 主题当前状态修改 retention.ms 配置的正确方式为什么不能使用 kafka-topics.sh&#xff1f;使用 kafka-configs.sh 动态更新配置 深入解析 retention 配置retention.ms 与 retention.bytes 的…...

React实现无缝滚动轮播图

实现效果&#xff1a; 由于是演示代码&#xff0c;我是直接写在了App.tsx里面在 文件位置如下&#xff1a; App.tsx代码如下&#xff1a; import { useState, useEffect, useCallback, useRef } from "react"; import { ImageContainer } from "./view/ImageC…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...