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魔术方法,只是将常见的几个魔术方法进行了简单的案例演示。

如有错误,请及时指出,感谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/585695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

山西电力市场日前价格预测【2023-12-31】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-12-31&#xff09;山西电力市场全天平均日前电价为445.23元/MWh。其中&#xff0c;最高日前电价为791.27元/MWh&#xff0c;预计出现在08:15。最低日前电价为270.52元/MWh&#xff0c;预计…

什么是SSL证书?在哪里免费申请?

随着互联网蓬勃发展&#xff0c;人们在日常生活中越来越依赖网络。然而&#xff0c;网络攻击和数据泄露日益猖獗&#xff0c;保护网站和用户信息的安全变得尤为紧迫。在这一背景下&#xff0c;SSL证书成为至关重要的安全措施。 SSL证书的首要功能在于防范网络攻击。相较于不安全…

MYSQL的UPDATE时锁表机制

&#xff08;笔记&#xff0c;只为获取流量券&#xff09; MySQL中&#xff0c;UPDATE 操作涉及到行级锁和表级锁的概念&#xff0c;具体取决于事务隔离级别和被更新的条件, 无索引的情况下&#xff1a; 当表没有索引的情况下&#xff0c;UPDATE 操作通常会涉及到表级锁。这是…

2023年末,软件测试面试题总结与分享

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;得准备年后面试了&#xff0c;又不知道从何下手&#xff01;为了帮大家节约时间&#xff0c;特意准备了一份面试相关的资料&#xff0c;内容非常的全面&#xff0c;真的可以好好补一补&#xff0c;希望大家在都能拿到…

Linux-权限

1.Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再 linux 系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在 linux 下做有限的事情。 超级用户的命令提示符是 “#” &#xff0c…

数字图像处理——亚像素边缘的轮廓提取

像素 像素是图像处理中的基本单位&#xff0c;一个像素是图像中最小的离散化单位&#xff0c;具有特定的位置和颜色信息。在数字图像中&#xff0c;每个像素都有一个特定的坐标&#xff0c;通常以行和列的形式表示。每个像素的颜色信息可以通过不同的表示方式&#xff0c;如灰…

MongoDB Certified Associate Developer 认证考试心得

介绍 前段时间通过了 MongoDB Associate Developer 考试&#xff0c;也记下了一些心得&#xff0c;结果忘记发出来了&#xff0c;现在重新整理下。通过考试后证书是这样的: MongoDB 目前有两个认证证书 1. MongoDB Associate Developer 认证掌握使用MongoDB 来构建现代应用…

苹果电脑Dock栏优化软件 mac功能亮点

hyperdock mac是一款Dock优化软件&#xff0c;hyperdock支持使用窗口自动排列功能&#xff0c;您可以直接通过将窗口拖拉至屏幕上方来快速最大化至全屏&#xff0c;又或者拖动到左右来进行左分屏和右分屏。而且Dock优化软件还有一个特色便是对Dock的强大管理哪里能力&#xff0…

《C++PrimerPlus》第13章 类继承

13.1 一个简单的基类 基类和派生类示例&#xff08;球会会员管理&#xff09; 头文件tabtenn1.h #ifndef __TABTENN1_H__ #define __TABTENN1_H__#include <iostream> #include <string>using namespace std;class TableTennisPlayer {private:string firstname;…

RS-485 RS-232 RS-422 区别和理解

RS-485&#xff0c;RS-232&#xff0c;RS-422区别和理解 目录概述需求&#xff1a; 设计思路实现思路分析1.概述2.区别 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a b…

【MySQL】数据库之存储过程(“SQL语句的脚本“)

目录 一、什么是存储过程&#xff1f; 二、存储过程的作用 三、如何创建、调用、查看、删除、修改存储过程 四、存储过程的参数&#xff08;输入参数&#xff0c;输出参数&#xff0c;输入输出参数&#xff09; 第一种&#xff1a;输入参数 第二种&#xff1a;输出参数 …

利用 IntelliJ IDEA 整合 GitHub 实现项目版本控制与协作管理

目录 前言1 设置GitHub登录账号2 将项目分享到GitHub3 IntelliJ IDEA 中导入Github项目4 往GitHub推送代码4.1 Commit Change&#xff08;提交到本地库&#xff09;4.2 Git -> Repository -> Push&#xff08;推送到远程库&#xff09; 5 拉取远程库代码到本地6 克隆远程…

Android MVC 写法

前言 Model&#xff1a;负责数据逻辑 View&#xff1a;负责视图逻辑 Controller&#xff1a;负责业务逻辑 持有关系&#xff1a; 1、View 持有 Controller 2、Controller 持有 Model 3、Model 持有 View 辅助工具&#xff1a;ViewBinding 执行流程&#xff1a;View >…

Ubuntu22.04系统安装软件、显卡驱动、cuda、cudnn、pytorch

Ubuntu22.04系统安装软件、显卡驱动、cuda、cudnn、pytorch 安装 Nvidia 显卡驱动安装 CUDA安装 cuDNN安装 VSCode安装 Anaconda 并更换源在虚拟环境中安装 GPU 版本的 PyTorchReference 这篇博文主要介绍的是 Ubuntu22.04 系统中软件、显卡驱动、cuda、cudnn、pytorch 等软件和…

STM32CubeMX教程8 TIM 通用定时器 - 输出比较

目录 1、准备材料 2、实验目标 3、实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.1、外设初始化函数调用流程 3.2.2、外设中断函数调用流程 3.2.3、添加其他必要代码 4、常用函数 5…

轮廓检测与处理

轮廓检测 先将图像转换成二值 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图 ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 变为二值&#xff0c;大于127置为255&#xff0c;小于100置为0.使用cv2.findContours(thresh, cv2.RETR_TREE, cv2.…

jvm实战之-常用jvm命令的使用

各命令的使用 JMAP 1、查看内存信息&#xff0c;对象实例数、对象占有大小 jmap -histo 进程号>./log.txt2、查看堆的配置信息和使用情况 jmap - heap 进程号3、将堆的快照信息dump下来&#xff0c;使用java自带的jvisualvm.exe打开分析 jmap -dump:formatb,filedump.h…

Elasticsearch:升级索引以使用 ELSER 最新的模型

在此 notebook 中&#xff0c;我们将看到有关如何使用 Reindex API 将索引升级到 ELSER 模型 .elser_model_2 的示例。 注意&#xff1a;或者&#xff0c;你也可以通过 update_by_query 来更新索引以使用 ELSER。 在本笔记本中&#xff0c;我们将看到使用 Reindex API 的示例。…

二叉树之堆的应用

目录 堆排序 思路详解 Ⅰ 建堆 Ⅱ 利用堆的删除思想来进行排序 功能接口 向上调整算法 向下调整算法 主函数 运行结果展示 TOP - K问题 思路详解 Ⅰ 用数据集合中前K个元素来建堆 Ⅱ 用剩余的N-K个元素依次与堆顶元素来比较&#xff0c;不满足则替换堆顶元素 功…

算法刷题:最大异或对(Trie树扩展)、食物链(并查集扩展)

目录 引言一、最大异或对&#xff08;Trie树扩展&#xff09;1.题目描述2.解题思路3.代码实现4.测试 二、食物链&#xff08;并查集扩展&#xff09;1.题目描述2.解题思路3.代码实现4.测试 引言 这两个扩展题能够让我们更加的熟悉Trie树和并查集的使用&#xff0c;这两道题可以…