php 各种魔术函数的触发条件
2024.3.20
1、__construct()
__construct() 用于在创建对象时自动触发
当使用 new 关键字实例化一个类时,会自动调用该类的 __construct() 方法
<?php
class MyClass {public function __construct() {echo "已触发 __construct 一次";}
}$obj = new MyClass(); // 创建对象时会输出 "已触发 __construct 一次"
?>
2、__destruct()
__destruct() 用于在对象被销毁时自动触发
对象的销毁对象的引用计数减少为零来触发
<?php
class MyClass {public function __construct() {echo "已触发 __construct 一次\n";}public function __destruct() {echo "已触发 __destruct 一次\n";}
}$obj = new MyClass(); //会触发 __construct
$a = unserialize($obj) //会触发 __destruct
?>
//由于php存在自动回收机制,在代码结束后会销毁 $obj 从而再一次触发 __destruct
//所以这段代码最终互返回两次"已触发 __destruct 一次"
3、__sleep()
序列化serialize() 函数会检查类中是否存在一个魔术方法sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。
此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组
如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误
<?php
class test
{public $var_1;public $var_2;public function __sleep() //在对象被序列化时触发{echo "已触发 __sleep() 一次\n";return ['var_1','var_2'];}
}$a = new test();
$a -> var_1 = 'var1';
$a -> var_2 = 'var2';
$b = serialize($a); //会触发 __sleep
var_dump($b);
?>
4、__weekup()
__weekup() 用于在反序列化对象时自动调用
unserialize() 会检查是否存在一个 wakeup() 方法,
如果存在,则会先调用wakeup()方法,预先准备对象需要的资源,返回void
常用于反序列化操作中重新建立数据库连接或执行其他初始化操作
<?php
class test
{public $var_1;public $var_2;public $var_wakeup;public function __wakeup() //在对象被反序列化时触发{echo "已触发 __wakeup 一次\n";$this -> var_wakeup = $this -> var_1;}
}$a = new test();
$a -> var_1 = 'var1';
$a -> var_2 = 'var2';
$b = serialize($a);
$c = unserialize($b); //会触发 __wakeup
var_dump($c);
?>
5、__tostring()
__tostring() 在对象被当做字符串处理时自动调用
比如echo、==、preg_match()
<?php
class test
{public $var_1;public function __tostring() //对象被当做字符串处理时触发{echo "已触发 __tostring 一次\n";return '1';}
}$a = new test;
$a == '123'; //会触发 __wakeup
echo $a; //会触发 __wakeup
?>
6、__invoke()
__invoke() 在对象被当做函数处理时自动调用
<?php
class test
{public $var_1='1';public function __invoke() //对象被当做函数处理时触发{echo "已触发 __invock 一次\n";}
}$a = new test('1');
$a(); //以函数的形式处理 $a 从而触发__invoke
?>
7、__call()
__call() 在调用一个不存在的方法时触发
<?php
class test
{public function __call($method, $args) //当调用一个不存在的方法时触发{echo "已触发 __call 一次\n";}
}$a = new test;
$a -> nothingness(''); //因为nothingness()方法不存在,所以触发了 __call
?>
8、__callStatic()
__callStatic() 在静态调用或调用成员常量时使用的方法不存在时触发
<?php
class test
{static public function __callStatic($method, $args){echo "已触发 __callStatic 一次\n"; }
}$a = new test(1);
$a::nothingness('a');
?>
9、__set()
__set() 在给不存在的成员属性赋值时触发
<?php
class test
{public $var_1;public $temp;public function __construct($var) //在对象被创建时触发{echo "已触发 __construct 一次\n";$this -> var_1 = $var;$this -> var_nothingness = '114514';}public function __set($name, $value) //在给不存在的成员属性赋值时触发{echo "已触发 __set 一次\n";}
}$a = new test(1);
?>
10、__isset()
__isset() 在对不可访问属性使用 isset() 或empty() 时会被触发
<?php
class temp
{private $no;public function __isset($name) //在给不存在的成员属性赋值时触发{echo "已触发 __isset 一次\n";}
}
class test
{public $var;public $temp;public function __construct($var){echo "已触发 __construct 一次\n";$this -> var_1 = $var;$temp = new temp;empty($temp->no); //用于触发 __isset}
}$a = new test(1);
?>
11、__unset()
__unset() 在对不可访问属性使用 unset() 时会被触发
<?php
class temp
{private $no;public function __unset($name) //对不可访问属性使用 unset() 会被触发{echo "已触发 __unset 一次\n";}
}
class test
{public $var;public $temp;public function __construct($var){echo "已触发 __construct 一次\n";$this -> var_1 = $var;$temp = new temp;unset($temp->no);}
}$a = new test(1);?>
12、__clone()
__clone() 当使用 clone 关键字拷贝完成一个对象后就会触发
<?php
class test
{public $var;public function __construct($var){echo "已触发 __construct 一次\n";$this -> var_1 = $var;clone($this); //用于触发 __clone}public function __clone() //当使用 clone 关键字拷贝完成一个对象后就会触发{echo "已触发 __clone 一次\n";}
}$a = new test(1);
?>
13、__get()
__get() 当尝试访问不可访问属性时会被自动调用
<?php
class Test
{private $data = array();public function __construct($var){echo "已触发 __construct 一次\n";$this->var_1 = $var;}public function __get($name){echo "已触发 __get 一次\n";if (isset($this->data[$name])) {return $this->data[$name];}}public function __set($name, $value){echo "已触发 __set 一次\n";$this->data[$name] = $value;}
}$a = new Test(1);
$a->v = 'a'; // 设置属性
echo $a->v; // 访问属性
var_dump($a);
?>
警告:以下代码是个人研究时写的,异常混乱,没有任何的逻辑和结果可言,大佬勿看,看完容易高血压,萌新勿看,看完容易裂开
<?phpclass temp
{private $no;public function __isset($name) //对不可访问属性使用 isset() 或empty() 会被触发{echo "已触发 __isset 一次\n";}public function __unset($name) //对不可访问属性使用 unset() 会被触发{echo "已触发 __unset 一次\n";}
}
class test
{public $var_1;public $var_2;public $var_wakeup;public $temp;private $data = array();public function __construct($var) //在对象被创建时触发{echo "已触发 __construct 一次\n";$this -> var_1 = $var;} public function __destruct() //在对象被销毁时触发{echo "已触发 __destruct 一次\n";$this(); //用于触发 __invoke}public function __sleep() //在对象被序列化时触发{echo "已触发 __sleep() 一次\n";$this::nothingness(''); //用于触发 __call$this -> var_nothingness = '114514'; //用于触发 __setreturn ['var_1','var_2'];}public function __wakeup() //在对象被反序列化时触发{echo "已触发 __wakeup 一次\n";if($this -> var_2 == '') //用于触发 __tostring{echo "比较通过\n";}$this -> var_wakeup = $this -> var_1;}public function __tostring() //对象被当做字符串处理时触发{echo "已触发 __tostring 一次\n";return '1';}public function __invoke() //对象被当做函数处理时触发{echo "已触发 __invock 一次\n";}public function __call($method, $args) //当调用一个不存在的方法时触发{echo "已触发 __call 一次\n";clone($this); //用于触发 __clone}static public function __callStatic($method, $args) //在静态调用或调用成员常量时使用的方法不存在时触发{echo "已触发 __callStatic 一次\n";$temp = new temp;isset($temp -> no); //用于触发 __issetunset($temp -> no); //用于触发 __unset}public function __clone() //当使用 clone 关键字拷贝完成一个对象后就会触发{echo "已触发 __clone 一次\n";}public function __get($name) //当尝试访问不可访问属性时会被自动调用{echo "已触发 __get 一次\n";$this-> name = "$name"; //用于触发 __set}public function __set($name, $value) //在给不存在的成员属性赋值时触发{echo "已触发 __set 一次\n";$this->data[$name] = $value;}
}//会触发一次 __construct 并在对象被销毁时触发一次 __destruct
//然后 __destruct 中的 $this() 又会触发 __invoke
$a = new test('var1');//会触发一次 __construct 并在对象被销毁时触发一次 __destruct
//然后 __destruct 中的 $this() 又会触发一次 __invoke
$a -> var_2 = new test('var2');//因为 $a 是一个对象,$a -> var_2 又是一个对象,会触发两次 __sleep
//__sleep中会调用不存在的函数和给不存在的值赋值,又会触发 __call 和 __set
//__call又会触发一次 __clone 和一次 __destruct
$b = serialize($a);//同理会触发会先触发两次 __wakeup 再触发两次 __destruct
//然后 __destruct 中的 $this() 又会触发 __invoke
//__wakeup中有比较,所以又会触发一次 __tostring
//注意:__tostring 是由 $a -> var_2 触发的,而 $a -> var_2 -> var_2 由于值为 NULL 是不会触发__tostring的
$c = unserialize($b);//会触发一次 __callStatic
//__callStatic 里面的 isset 会触发一次 __isset,unset 会触发一次 __unset
$c::nothingness('');//会触发一次 __get
//__get 又触发一次 __set
echo $c -> v;//var_dump($c);
相关文章:
php 各种魔术函数的触发条件
2024.3.20 1、__construct() __construct() 用于在创建对象时自动触发 当使用 new 关键字实例化一个类时,会自动调用该类的 __construct() 方法 <?php class MyClass {public function __construct() {echo "已触发 __construct 一次";} }$obj new …...
Linux的学习之路:2、基础指令(1)
一、ls指令 上篇文章已经说了一点点的ls指令,不过那还是不够的,这篇文章会介绍更多的指令,最起码能使用命令行进行一些简单的操作,下面开始介绍了 ls常用选项 -a 列出目录下的所有文件,包括以 . 开头的隐含文件。 -d…...
0103设计算法-算法基础-算法导论第三版
文章目录 一、分治法二、分析分治算法结语 我们可以选择使用的算法设计技术有很多。插入排序使用了增量方法:在排序子数组 A [ 1 ⋯ j − 1 ] A[1\cdots j-1] A[1⋯j−1]后,将单个元素 A [ j ] A[j] A[j]插入子数组的适当位置,产生排序好的子…...
[NCTF2019]SQLi ---不会编程的崽
欸嘿,继续sql注入。又是新的sql注入类型 很直接哦,给出了sql查询语句。简单扫描一下,robots.txt还能访问。里边提示hint.txt $black_list "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00…...
上位机开发 halcon坐标转轴坐标
背景 上位机开发中有一种相机叫标定相机,主要是有来给某些要进行根据CAD图点位计算时当前产品实际点位坐标时使用的一种标定测量相机。主要原理是根据两个或多个指定的标定点进行取图计算圆心坐标,再将视觉计算出的圆心坐标和取图时的轴坐标进行偏差计算。最后得到标定点轴的…...
[数据结构]二叉树(下)
一、二叉树的节点和深度关系 1.满二叉树 我们可以假设二叉树有N个节点,深度为h我们可以恒容易得到满二叉树每行的节点数,然后错位相减,算出节点与高度的关系。 2.完全二叉树 注意我这个是因为最后一行的节点数为1。 二、向上调整建堆和向下调整建堆的时…...
动手学深度学习|notebook教程
D2L.AI|《动手学深度学习》Notebooks 目录 面向中文读者的能运行、可讨论的深度学习教科书 含 PyTorch、NumPy/MXNet、TensorFlow 和 PaddlePaddle 实现 被全球 70 多个国家 500 多所大学用于教学 github 下面是整理好的,可以直接运行的notebook 0 前…...
C#面:简述 .NET Framework 类库中的“命名空间”
在 C# 中,命名空间(Namespace)是一种用于组织和管理代码的机制。它提供了一种将相关的类、接口、结构体和其他类型组织在一起的方式,以便更好地管理和维护代码。 .NET Framework类库中的命名空间是一种逻辑上的分组,它…...
android.os.TransactionTooLargeException解决方案,Kotlin
android.os.TransactionTooLargeException解决方案,Kotlin 首先,特意制造一个让Android发生TransactionTooLargeException的场景,一个Activity启动另外一个Activity,在Intent的Bundle里面塞入一个大的ArrayList: import android.…...
ChatGPT智能聊天系统源码v2.7.6全开源Vue前后端+后端PHP
测试环境:Linux系统CentOS7.6、宝塔、PHP7.4、MySQL5.6,根目录public,伪静态thinkPHP,开启ssl证书 具有文章改写、广告营销文案、编程助手、办公达人、知心好友、家庭助手、出行助手、社交平台内容、视频脚本创作、AI绘画、思维导图等功能 ai通道:文心一言、MiniMax、智…...
汇丰:当前的美股是泡沫吗?
汇丰认为,当前的风险资产并不构成泡沫,更类似于2017年的市场环境,风险资产有望继续稳步上升。 隔夜美股飙涨,标普创三个月最大周涨,纳指收盘创历史新高。结合去年以来的强劲表现,有观点认为由科技股支撑的…...
颠覆传统:Web3如何塑造未来的数字经济
引言 近年来,随着数字化时代的到来,互联网已经成为人们生活中不可或缺的一部分。然而,随着技术的不断发展和社会的不断变迁,传统的Web2模式逐渐显露出一些弊端,如数据垄断、隐私泄露等问题,这促使人们寻求…...
iOS模拟器 Unable to boot the Simulator —— Ficow笔记
本文首发于 Ficow Shen’s Blog,原文地址: iOS模拟器 Unable to boot the Simulator —— Ficow笔记。 内容概览 前言终结模拟器进程命令行改权限清除模拟器缓存总结 前言 iOS模拟器和Xcode一样不靠谱,问题也不少。😂 那就有病治…...
使用 Flink + Faker Connector 生成测试数据压测 MySQL
博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…...
Android单片机硬件通信《GPIO通信》
一、什么是GPIO? GPIO(英语:General-purpose input/output),通用型输入输出端口,在单片机上一般是通过一个GND引脚和若干个io引脚配合工作。 单片机可以配置GPIO输入输出模式,与外界环境进行通信交互。在输入环境下&…...
C# WPF编程-事件
C# WPF编程-路由事件 路由事件概要路由事件的三种方式 WPF事件WPF最重要的5类事件:生命周期事件 鼠标事件键盘事件多点触控输入原始触控 路由事件概要 路由事件是具有更强传播能力的事件,它们可在元素树中向上冒泡和向下隧道传播,并沿着传播…...
C语言 预处理器 注释 基本案例讲解
上文 程序设计语言与C语言发展 我们简述了 计算机语言的发展 以及编程语言与指令的概念 那么 今天 我们就来 初始C语言 并完成 第一个C语言案例 这里 我们需要完成 C语言 Hello World案例 以及 C语言程序举例 任何编程语言 开始的案例 都是 Hello World 所以说 Hello World 是…...
Flutter学习10 - Json解析与Model使用
对于网络请求返回的 Json 数据,一般会进行如下解析: 将 Json String 解析为 Map<String, dynamic>将 Json String 解析为 Dart Model 发起一个返回 Json String 的网络请求 import package:http/http.dart as http;void main() {_doGet(); }_do…...
Clickhouse异常:Exception: No operation equals between Decimal(X, X) and Float64
在使用clickhouse中的Decimal类型存储数字时,使用Decimal类型字段作为查询条件时,比如: SELECT COUNT(*) AS total FROM table WHERE ( my_number10.2) 会报错如下:Exception: No operation equals between Decimal(X, X) and F…...
会员中心微服务
文章目录 1.环境配置1.创建会员中心模块2.检查父子模块的pom.xml1.父模块注意:如果父模块中的依赖显示not found,原因是子模块并没有引用,不用在意 2.子模块 3.pom.xml 引入相关依赖(别忘记刷新maven)4.application.ym…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
