PHP序列化总结2--常见的魔术方法
魔术方法的概念
PHP的魔术方法是一种特殊的方法,用于覆盖PHP的默认操作。它们以双下划线(__)开头,后面跟着一些特定的字符串,如__construct()、__destruct()、__get()等。这些魔术方法在对象执行特定操作时被自动调用,从而允许开发人员对这些操作进行自定义处理。
常见的魔术方法列举
__construct:在实例化一个类时触发__destruct:在一个实例对象被销毁时触发__set(string $name , mixed $value):设置一个不能访问的成员属性时触发__get(string $name):获得一个不能访问的成员属性时触发__call($name,$arguments):访问一个不能访问的成员方法时触发__callStatic($name,$arguments):访问一个不能访问的成员静态方法时触发__toString:将一个对象实例被当成字符串时触发__clone:在创建一个新对象时触发__invoke:当以函数的方式调用对象时触发__sleep:在对一个对象的数据处理,不需要保存全部数据时触发,如: serialize()序列化时__wakeup: 在unserialize()时,会先检查是否有__wakeup方法__unset(string $name):在一个不可访问的对象属性被unset时触发__isset(string $name):在一个不可访问的对象属性被isset,empty时触发__debugInfo:当一个对象被var_dump时触发__set_state:当一个对象被var_export时触发
案例分析
__construct()函数:在一个对象创建的时候,如果类中有这个方法就会被触发
__destruct()函数:在一个对象被销毁的时候被触发,销毁可以是程序执行完成后自动销毁也可以是使 用相关方法进行人为销毁
<?php
//__construct() 和__destruct()
class Test{
public $name;
public $age;
public $string;
public function __construct($name,$age,$string){ echo "__construct 初始化"."<br>";
$this->name=$name;
$this->age=$age;
$this->string =$string;
}
function __destruct(){
echo "__destruct 类执行完毕"."<br>"; }}
$test= new Test("spaceman",566,"Test String");
unset($test);//人为销毁对象
echo '第一种执行完毕 '.'<br>';
echo '----------------<br>';
$test2 = new Test("Spaceman",5566,"Test String"); echo '第二种执行完毕 '.'<br>';
//程序自动销毁
结果展示

unset()是主动销毁对象,可以触发__destruct()函数,在程序结束后,创建的对象也会被自动销毁,因此也会触发 destruct()函数,这种执行会在所有程序结束后执行,为此我们可以看到两种方式的执行的显示结果有区别
__toString()函数:当对象被当做字符串使用的时候会被调用
<?php
class Test{
public $variable ="This is a string";
public function good(){
echo $this->variable.'<br/>';public function __toString(){
return '__toString<br>';
}
}
$a = new Test;
$a->good();
echo $a;
结果展示

变量a是我们新建的一个对象,但是我们如果将其输出,就会自动触发__toString()魔术方法
__call()函数:在调用不存在的方法的时候会触发执行
<?php
class Test{
public function good($number,$string){
echo '存在good()方法 '.'<br>';
echo $number.'-------------'.$string.'<br>';
}
public function __call($method,$args){
echo '不存在 '.$method.'方法 '.'<br>';
var_dump($args);
}}
$a = new Test();
$a->good(566,'nice');
$b = new Test();
$a->sperman(788,'no');
结果展示

当我们创建一个对象,这个对象中有__call()方法如果我们使用这个对象的时候调用了类中不存在的方法就会触发call()魔术方法
__get()函数:在调用不存在的成员变量的时候会被调用
class Test{
public $n=33;
public function __get($name){
echo '__get不存在成员变量 '.$name.'<br>';}
}$a= new Test();
//a中存在的成员变量
echo $a->n;
echo '<br>';
//a中不存在的成员变量
echo $a->spaceman;
结果展示

如果一个类的中有__get()方法,我们使用该类实例化的对象如果调用其中不存在的成员属性,就会触发__get()方法
__set()函数:设置一个对象的属性时,若对象的属性存在,那么就会直接设置对象的属性,如果对象的 属性不存在,那么就会触发__set()方法
<?php
class Test{
public $data = 100;
public $noway=0;
public function __set($name,$value){
echo '__set 不存在成员变量 '.$name.'<br>';
$this->noway=$value;
}}
$a= new test();
$a->noway=566;
$a->spaceman=566;
$a->get();
结果展示

设置一个对象的属性的时候,如果属性值存在,那么就直接赋值。如果属性值不存在,就会调 用set函数
_sleep()函数 :使用serialize()函数会被调用
<?php
class Test{ public $name; public $age;public $tring;public function __construct($name,$age,$string){ echo '__construct 初始化 '.'<br>';$this->name=$name;$this->age=$age;$this->string=$string;}
public function __sleep(){echo "当类外部使用serialize()时会调用这里的sleep()方法<br>"; return array('name','age');
}
}
$a= new Test("Spaceman",556,"Test String");
serialize($a);
结果展示

我们创建完对象后就会触发里面的__sleep()函数执行里面的代码
_wakeup()函数:在unserialize()时候触发
<?php
class Test {
public $sex;
public $name;
public $age;
public function __wakeup(){
echo '当外部实体使用unserialize是会调用这里的wakeup()方法<br>'; $this->age=556;
}
}$person= new Test('spaceman',21,'男 ');
$a=serialize($person);
//echo $a."<br>";
var_dump(unserialize($a));
结果展示

我们创建完对象后进行反序列化就会触发里面的__wakeup()函数执行里面的代码
__isset()函数:当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被触发
<?php
class Person{public $sex;private $name;private $age;public function __construct($name, $age, $sex){$this->name = $name;$this->age = $age;$this->sex = $sex;}// __isset():当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。public function __isset($content){echo "当在类外部使用isset()函数测定私有成员 {$content} 时,自动调用<br>";return isset($this->$content);}
}$person = new Person("spaceman", 25,'男');
echo ($person->sex),"<br>";
echo isset($person->name);
结果展示

我们使用__isset()函数去判断了私有属性的话就会自动触发isset()其中的内容
__unset()函数:在不可访问的属性上使用unset()时触发 销毁对象的某个属性时执行此函数
class Person{public $sex;private $name;private $age;public function __construct($name, $age, $sex){$this->name = $name;$this->age = $age;$this->sex = $sex;}// __unset():销毁对象的某个属性时执行此函数public function __unset($content) {echo "当在类外部使用unset()函数来删除私有成员时自动调用的<br>";echo isset($this->$content)."<br>";}
}$person = new Person("spaceman", 21,"男"); // 初始赋值
echo "666666<br>";
unset($person->name);//调用 属性私有
unset($person->age);//调用 属性私有
unset($person->sex);//不调用 属性共有
结果展示

当我们使用unset销毁对象里面的私有属性就会触发其中的unset()方法,上例中,我们销毁了两个私有属性为此unset方法被触发了两次
_invoke():以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用
<?php
class Test{// _invoke():以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用public function __invoke($param1, $param2, $param3)
{echo "这是一个对象<br>";var_dump($param1,$param2,$param3);}
}$a = new Test();
$a('spaceman',21,'男');
结果展示

我们创建了一个Test对象a,Test对象中有一个_invoke()函数,我们在使用对象a的时候,以函数的形式进行了传参,触发了invoke()方法
写在最后
案例演示中并没有列举完所有的php魔术方法,只是将常见的几个魔术方法进行了简单的案例演示。
如有错误,请及时指出,感谢
相关文章:
PHP序列化总结2--常见的魔术方法
魔术方法的概念 PHP的魔术方法是一种特殊的方法,用于覆盖PHP的默认操作。它们以双下划线(__)开头,后面跟着一些特定的字符串,如__construct()、__destruct()、__get()等。这些魔术方法在对象执行特定操作时被自动调用…...
Docker 入门 ------容器互通以及Dockerfile
1. 端口映射以及容器互联 Docker 除了通过网络访问,还提供了两种很方便的功能来满足服务访问的基本需求: 允许映射容器内应用的服务端口到本地宿主主机互联机制实现多个容器间通过容器名来快速访问 1.1 容器映射实现访问容器 1.1.1 从外部访问容器应…...
AI绘图模型不会写字的难题解决了
介绍 大家好,最近有个开源项目比较有意思,解决了图像中不支持带有中文的问题。 https://github.com/tyxsspa/AnyText。 为什么不能带有中文? 数据集局限 Stable Diffusion的训练数据集以英文数据为主,没有大量包含其他语言文本的…...
vue-cli创建项目时由esLint校验导致报错或警告的问题及解决
vue-cli创建项目时由esLint校验导致报错或警告的问题及解决 一、万能办法 一、万能办法 //就是在报错的JS文件中第一行写上 /* eslint-disable */链接: https://www.yii666.com/blog/288808.html 其它的方法我遇见了再补充...
uniapp:实现手机端APP登录强制更新,从本地服务器下载新的apk更新,并使用WebSocket,实时强制在线用户更新
实现登录即更新,或实时监听更新 本文介绍的是在App打开启动的时候调用更新,点击下方链接,查看使用WebSocket实现实时通知在线用户更新。 uniapp:全局消息是推送,实现app在线更新,WebSocket,ap…...
设计循环队列——oj题622
. 个人主页:晓风飞 专栏:LeetCode刷题|数据结构|Linux 路漫漫其修远兮,吾将上下而求索 文章目录 题目要求:应该支持如下操作:示例:提示: 结构体定义队列的创建基本操作判断队列是否为空…...
阿里后端实习一面面经
阿里后端实习一面面经 项目中使用到了es,es的作用? elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 es中的重要概念? 群集:一个或多个节点…...
element-ui组件DatePicker日期选择器移动端兼容
element-ui组件DatePicker日期选择器移动端兼容 css /** 移动端展示 **/ media screen and (max-width: 500px) {.el-picker-panel__sidebar {width: 100%;}.el-picker-panel {width: 400px!important;}.el-picker-panel__content {width: 100%;}.el-picker-panel__body{marg…...
burpsuite 爆破
靶场搭建:phpstudy的安装与靶场搭建 - junlin623 - 博客园 (cnblogs.com) 账号字典:XXTK: 一些弱口令、fuzz字典 (gitee.com) 网盘链接:https://pan.baidu.com/s/1v5pAwaTwoeCnJgkUXf3iLQ?pwd=mllm 提取码:mllm --来自百度网盘超级会员V2的分享 一、暴力破解 - 基于…...
SparkSQL基础解析(三)
1、 Spark SQL概述 1.1什么是Spark SQL Spark SQL是Spark用来处理结构化数据的一个模块,它提供了2个编程抽象:DataFrame和 DataSet,并且作为分布式SQL查询引擎的作用。 我们已经学习了Hive,它是将Hive SQL转换成MapReduce然后提…...
gz-hamonic 安装提示缺少许多依赖无法安装
在软件更新源中增加gz-hamonic的软件源, 点击添加,在输入框中填入如下语句: deb http://packages.osrfoundation.org/ubuntu jammy main 如图所示: 然后执行 sudo apt -get install gz-hamonic即可安装。 如下图 在终端中输入…...
新版Edge卸载
新版Edge卸载:步骤与注意事项 随着Windows 10的发布,微软推出了新版Edge浏览器。虽然新版Edge浏览器具有许多优秀的新功能和改进,但有时您可能希望卸载它并使用其他浏览器。在本文中,我们将向您介绍如何卸载新版Edge浏览器&#…...
Ansibe自动化基础
目录 一.Ansibe自动化概述 1.特点 2.工作特性 3.应用场合 二.ansibe安装即相关文件说明 1.安装 2.相关文件 3.主配置文件内容详解 4.ansibe运行机制 三.ansibe管理节点命令 1.Ansibe 四.主机组配置 1.基本配置 第一种: 第二种: 2.设置SSH…...
2023 年中国高校大数据挑战赛赛题B DNA 存储中的序列聚类与比对-解析与参考代码
题目背景:目前往往需要对测序后的序列进行聚类与比对。其中聚类指的是将测序序列聚类以判断原始序列有多少条,聚类后相同类的序列定义为一个簇。比对则是指在聚类基础上对一个簇内的序列进行比对进而输出一条最有 可能的正确序列。通过聚类与比对将会极大…...
决策树--分类决策树
1、介绍 ① 定义 分类决策树通过树形结构来模拟决策过程,决策树由结点和有向边组成。结点有两种类型:内部结 点和叶结点。内部结点表示一个特征或属性,叶子节点表示一个类。 ② 生成过程 用决策树分类,从根结点开始ÿ…...
【2024/1/5】
2024/1/5周报 本周开展工作下周工作计划 本周开展工作 首先的话就是跟大家汇报一下上一个项目的进度,那因为一些我这边的不可控的因素暂时进行搁置,随后的话还是需要在进行做的。 因此我们最近在做一个web端的项目,这个项目的具体的就不汇报…...
CNN——VGG
1.VGG简介 论文下载地址:https://arxiv.org/pdf/1409.1556.pdf VGGNet 是由牛津大学视觉几何小组(Visual Geometry Group, VGG)提出的一种深层卷积网络结构,他们以 7.32% 的错误率赢得了 2014 年 ILSVRC 分类任务的亚军ÿ…...
深入理解Java中的多线程编程与并发控制
当谈论到 Java 编程语言时,多线程编程和并发控制是其中最重要的话题之一。Java 在多线程领域有着强大的支持和丰富的工具集,允许开发人员利用并发性来提高程序性能和效率。本文将深入探讨 Java 中的多线程编程和并发控制,包括线程的创建、同步…...
提供10个mysql的实例和思路
学生信息管理系统 学生表(id, name, gender, age, class_id)班级表(id, name)思路:通过学生表和班级表进行关联,可以实现学生信息的查询、添加、修改、删除等操作。 订单管理系统 订单表(id, us…...
FPGA项目(14)——基于FPGA的数字秒表设计
1.功能设计 设计内容及要求: 1.秒表最大计时范围为99分59. 99秒 2.6位数码管显示,分辨率为0.01秒 3.具有清零、启动计时、暂停及继续计时等功能 4.控制操作按键不超过二个。 2.设计思路 所采用的时钟为50M,先对时钟进行分频,得到100HZ频率…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
