一篇文章带你入门PHP魔术方法

PHP魔术方法

PHP 中的"魔术方法"是一组特殊的方法,它们在特定情况下自动被调用。这些方法的名称都是以两个下划线(__)开头。魔术方法提供了一种方式来执行各种高级编程技巧,使得对象的行为可以更加灵活和强大。以下是一些常见的PHP魔术方法:

  1. __construct(): 构造函数,当一个新对象被创建时调用。
  2. __destruct(): 析构函数,当一个对象不再被使用时调用。
  3. __call($name, $arguments): 当调用一个对象中不存在的方法时调用。
  4. __callStatic($name, $arguments): 当调用一个静态方法不存在时调用。
  5. __get($name): 当读取一个不可访问的属性时调用。
  6. __set($name, $value): 当设置一个不可访问的属性时调用。
  7. __isset($name): 当对不可访问的属性调用 isset()empty() 时调用。
  8. __unset($name): 当对不可访问的属性调用 unset() 时调用。
  9. __sleep(): 在序列化对象之前调用,通常用于清理任务或返回数组中的哪些属性需要被序列化。
  10. __wakeup(): 在反序列化对象时调用,通常用于重新建立数据库连接或执行其他初始化操作。
  11. __toString(): 当对象被当作字符串使用时调用,例如在 echo 语句中。
  12. __invoke(): 当尝试将对象当作函数调用时执行。
  13. __set_state($array): 当调用 var_export() 且返回的结果被执行时调用。
  14. __clone(): 当对象被克隆时调用。

这些魔术方法提供了对对象生命周期中各种事件的控制,以及对对象行为的定制化。正确和恰当地使用这些方法可以使你的代码更加健壮和灵活

掌握PHP魔术方法分为触发时机--->功能--->参数-->返回值

最低要求:起码知道触发时机,不然对之后pop链的学习影响会很大

很感谢陈腾老师的教导!

接下来我会带领大家一一学习PHP魔术方法

接下来都会是代码加解释的形式和大家一起·学习,

1.——construct()

<?php
highlight_file(__FILE__);
class User {
    public $username;
    public function __construct($username) {
        $this->username $username;
        echo "触发了构造函数1次" ;
    }
}
$test = new User("benben");
$ser serialize($test);
unserialize($ser);

?>

输出:触发了构造函数1次

这里是先定义一个类User,下面的public是全局变量的意思,这里提一下,如果使用的是private,那就是属于一个私有属性,也就是说你只能在User这个类里面使用,如果你在外面调用了它,肯定是不行的。接下来public function __construct($username) {
        $this->username $username;
        echo "触发了构造函数1次" ;
    }这里就是一个魔术方法,

换句话来说就是user这个类里面有username,和一个魔术方法,后面的代码就是调用user这个类里面的属性而已

搞懂了代码就好说了!$test = new User("benben");这里是实例化对象,所以只会在这行代码触发,输出“触发了构造函数1次”

这个__construct()魔术方法很简单

触发时机:实例化对象时会触发比如($test = new User("benben");)这里就时实例化对象

功能就是:提前清理不必要的内容

参数:非必要

返回值:

2.__destruct()

在对象的所有的引用被删除或者当对象被显示销毁时执行的魔术方法

比如:<?php
highlight_file(__FILE__);
class User {
    public function __destruct()
    {
        echo "触发了析构函数1次"."<br />" ;
    }
}
$test = new User("benben");
$ser serialize($test);
unserialize($ser);

?>
触发了析构函数1次
触发了析构函数1次

__destruct()

触发时机:对象引用完成或对象被销毁;反序列化之后

功能:

参数:

返回值:

来到题目:

<?php
highlight_file
(__FILE__);
error_reporting(0);
class 
User {
    var 
$cmd "echo 'dazhuang666!!';" ;
    public function 
__destruct()
    {
        eval (
$this->cmd);
    }
}

$ser $_GET["benben"];
unserialize($ser);

拿到这道题目,就直接徒手构造就好了,benben=O:4:"User":1:{s:3:"cmd";s:13:"system('id');";}

首先是object:User对应的是四个字符,里面只有1个成员属性,最后的“;”不要忘记。

直接拿下,这里直接反序列化的时候就已经触发了——dstruct()

3._sleep()

触发时机:_slee[()先执行;序列化之后再执行,也就是序列化前调用

功能:

参数:

返回值:

<?php
highlight_file(__FILE__);
class User {
    const SITE 'uusama';
    public $username;
    public $nickname;
    private $password;
    public function __construct($username$nickname$password)    {
        $this->username $username;
        $this->nickname $nickname;
        $this->password $password;
    }
    public function __sleep() {
        return array('username''nickname');
    }
}
$user = new User('a''b''c');
echo serialize($user);
?>

O:4:"User":2:{s:8:"username";s:1:"a";s:8:"nickname";s:1:"b";}

这串代码的意思是一个对象user,还有它的对应属性。

接下来直接_construct魔术方法,因为最下面new User会触发

这个魔术方法,但是后面的sleep遇到serialize又会触发魔术方法_sleep(),这里先触发——construct(),(在实例化前触发)并且把username,nickname,password,为别赋值a,b,c

这里本来应该输出的是三个参数的,但是后面的sleep又触发魔术方法,结果password就不输出

4._wakeup()

这个在做反序列化unserialize()之前触发

触发时机:这个在做反序列化unserialize()之前触发

功能:

参数:

返回值:返回void

<?php
highlight_file
(__FILE__);
error_reporting(0);
class 
User {
    const 
SITE 'uusama';
    public 
$username;
    public 
$nickname;
    private 
$password;
    private 
$order;
    public function 
__wakeup() {
        
system($this->username);
    }
}

$user_ser $_GET['benben'];
unserialize($user_ser);
?>

?benben=O:4:”User”:1:{s:8:”username”;s:2:”id”;}

这里构造1个就好,因为_wakeup()过后就只调用username,其他几个属性就没有必要写了

Ps:反序列化里面对字符串包裹就只能使用双引号,单引号不识别

5._tostring()

触发时机:把对象被当成字符串调用

功能:

参数:

返回值:

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    var $benben "this is test!!";
         public function __toString()
         {
             return '格式不对,输出不了!';
          }
}
$test = new User() ;
print_r($test);
echo "<br />";
echo $test;
?>
User Object ( [benben] => this is test!! )
格式不对,输出不了!(这个命令是 $test)所触发的

把类User实例化并且赋值给$test,此时的$test是个对象,调用对象可以使用print_

或者是var_dump

但是如果使用echo或者print只能调用字符串的方式去调用对象,即把对象当成字符串使用,此时自动触发tostring()

也就是说后面的echo $test直接当成字符串输出了,这里会触发魔术方法tostring()

6._invoke()

触发时机:把对象被当成函数调用

功能:

参数:

返回值:

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    var $benben "this is test!!";
         public function __invoke()
         {
             echo  '它不是个函数!';
          }
}
$test = new User() ;
echo $test ->benben;
echo "<br />";
echo $test() ->benben;
?>
this is test!!
它不是个函数!

其实跟tostring差不多,就是(echo $test() ->benben)这里直接把它当成函数输出导致了魔术方法触发

7._call()

触发时机:调用了一个根本不存在的方法

功能:

参数:2个参数$arg1,$arg2

返回值:调用的不存在的方法的名称和参数

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    public function __call($arg1,$arg2)
    {
        echo "$arg1,$arg2[0]";
          }
}
$test = new User() ;
$test -> callxxx('a');
?>

输出:callxxx,a

$test =new User()这句话是把new User()实例化成为一个对象给$test,接下来从test调用出来一个方法callxxx,并且给他传了个参数是a,但是这里根本没有callxxx,所以做不到,这里就触发了魔术方法

$arg1是方法,$arg2是参数

8._callstatic()

触发时机:静态调用或调用成员常量时使用

功能:

参数:2个参数$arg1,$arg2

返回值:调用的不存在的方法的名称和参数


<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    public function __callStatic($arg1,$arg2)
    {
        echo "$arg1,$arg2[0]";
          }
}
$test = new User() ;
$test::callxxx('a');
?>

callxxx,a

这里跟_call()差不多一样的,只不过这个是静态调用(比如$test::callxxx('a');)时使用而已,不是静态调用就不会触发,你可以把::改一下,看看别的还会不会触发


9.__get()

触发时机:调用的成员属性不存在

功能:

参数:

返回值:不存在的成员属性的名称

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    public $var1;
    public function __get($arg1)
    {
        echo  $arg1;
    }
}
$test = new User() ;
$test ->var2;
?>

输出:
var2

这里其实就是少了一个参数var2,但是$test ->var2;这里却要输出var2,所以就会触发get()魔术方法,自动帮你添加一个var2上去

10._set()

触发时机:给不存在的成员属性赋值

功能:

参数:

返回值:不存在的成员属性的名称和赋的值

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    public $var1;
    public function __set($arg1 ,$arg2)
    {
        echo  $arg1.','.$arg2;
    }
}
$test = new User() ;
$test ->var2=1;
?>

输出:
var2,1

11._isset()

对一个被保护的属性或者根本就不存在的属性,或者私有属性

触发时机:对不可访问属性使用isset()或empty()时,__isset()就会被调用

功能:

参数:

返回值:不存在的成员属性的名称

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    private $var;
    public function __isset($arg1 )
    {
        echo  $arg1;
    }
}
$test = new User() ;
isset($test->var);
?>
输出:
var

比如这段代码,因为这里的var只能在当前类中使用,因为这是一个私有属性,你出来后调用肯定不可以,这里一定会触发——isset()魔术方法,最终顺利输出var

12._unset()

触发时机:对不可访问属性使用__unset()时

功能:

参数:

返回值:不存在的成员属性的名称

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    private $var;
    public function __unset($arg1 )
    {
        echo  $arg1;
    }
}
$test = new User() ;
unset($test->var);
?>

输出:
var

13._clone()

触发时机:使用clone关键字拷贝完成一个对象后,新对象会自动调用定义的魔术方法__clone()

就是说使用clone()克隆对象完成后,就会触发魔术方法__clone()

功能:

参数:

返回值:

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    private $var;
    public function __clone( )
    {
        echo  "__clone test";
          }
}
$test = new User() ;
$newclass = clone($test)
?>

输出:
__clone test

真心希望我的文章能够让大家有所收获!

总结

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

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

相关文章

DSG YashanDB数据交互解决方案:更稳、更快、更安全

近期&#xff0c;深圳计算科学研究院&#xff08;简称“深算院”&#xff09;携手迪思杰&#xff08;北京&#xff09;数据管理技术有限公司&#xff08;简称“DSG”&#xff09;重磅推出基于崖山数据库的数据交互解决方案&#xff0c;具备双向迁移同步、性能稳定、支持复杂对象…

余弦相似度算法

余弦相似度算法 是什么 余弦距离&#xff0c;也称为余弦相似度&#xff0c;是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量。 余弦值越接近1&#xff0c;就表明夹角越接近0度&#xff0c;也就是两个向量越相似&#xff0c;这就叫"余弦相似性&q…

AD20PCB笔记(写给第三次重学PCB的自己)

readme&#xff1a;我曾以为自己本科毕业以后&#xff0c;再也不会用到PCB了&#xff0c;因为本科毕设的时候自己设计的PCB开发板出现了严重的设计问题&#xff0c;在实际测试的过程中&#xff0c;电源一上电&#xff0c;板子芯片直接炸飞&#xff0c;当时真的让我很害怕&#…

c++学习笔记(10)-可变参数模板

1、概念 可变参数模板&#xff08;Variable Template Parameters&#xff09;是 C11 中引入的一种语法&#xff0c;它允许函数或类模板接受可变数量的参数。这样可以方便地定义操作适用于多个类型和/或值的函数或类模板。 使用可变参数模板时&#xff0c;可以在模板参数列表中…

机器学习距离度量方法

1. 机器学习中为什么要度量距离&#xff1f; 机器学习算法中&#xff0c;经常需要 判断两个样本之间是否相似 &#xff0c;比如KNN&#xff0c;K-means&#xff0c;推荐算法中的协同过滤等等&#xff0c;常用的套路是 将相似的判断转换成距离的计算 &#xff0c;距离近的样本相…

K-means 聚类算法分析

算法简述 K-means 算法原理 我们假定给定数据样本 X &#xff0c;包含了 n 个对象 &#xff0c;其中每一个对象都具有 m 个维度的属性。而 K-means 算法的目标就是将 n 个对象依据对象间的相似性聚集到指定的 k 个类簇中&#xff0c;每个对象属于且仅属于一个其到类簇中心距离…

Jetson Orin安装riva以及llamaspeak,使用 Riva ASR/TTS 与 Llama 进行实时交谈,大语言模型成功运行笔记

NVIDIA 的综合语音 AI 工具包 RIVA 可以处理这种情况。此外&#xff0c;RIVA 可以构建应用程序&#xff0c;在本地设备&#xff08;如 NVIDIA Jetson&#xff09;上处理所有这些内容。 RIVA 是一个综合性库&#xff0c;包括&#xff1a; 自动语音识别 &#xff08;ASR&#x…

Java创建线程执行任务的方法(一)

目录 1.继承Thread类 2.实现Runnab类 2.1实现Runnable类 2.2使用Lambda表达式 3.实现Callable类 3.1返回Integer类型数据 3.2返回String类型数据 3.3返回Object类型数据 4.匿名内部类 创建线程的方法&#xff1a;继承Thread类&#xff1b;实现Runnab类&#xff1b;匿名…

如何文件从电脑传到iPhone,这里提供几个方法

本文介绍了如何使用Finder应用程序、iTunes for Windows、iCloud和谷歌照片将照片从Mac或PC传输到iPhone。 如何将照片从Mac传输到iPhone 如果你有一台Mac电脑&#xff0c;里面装满了你想转移到iPhone的照片&#xff0c;这是一件非常简单的事情。只需遵循以下步骤&#xff1a…

Python中matplotlib库的使用1

1 matplotlib库简介 matplotlib是一个数学绘图库&#xff0c;可以将数据通过图形的方式显示出来&#xff0c;也就是数据可视化。 2 matplotlib库的安装 2.1 打开cmd窗口 点击键盘的“Win”“R”键&#xff0c;在弹出的“运行”对话框的“打开”栏中输入“cmd”&#xff0c;…

【UE5.1】程序化生成Nanite植被

目录 效果 步骤 一、下载Gaea软件和树林资产 二、使用Gaea生成贴图 三、 生成地形 四、生成草地 五、生成树林 六、生成湖泊 七、其它功能介绍 7.1 调整树林生成的面积 7.2 让植物随风飘动 7.3 玩家和植物互动 7.4 雪中树林 7.5 环境音效 效果 步骤 一、下载Ga…

循环冗余效验码的计算方法

循环冗余效验码的计算方法 G&#xff08;x&#xff09;&#xff1a; 在了解计算方法之前我们首先要明白G&#xff08;x&#xff09;表明的意思&#xff0c;这一步非常重要&#xff01; 例如&#xff0c;G&#xff08;x&#xff09; x^3 x^2 1 &#xff0c;该式子表明的编…

vue3 数据转换

只需要添加 const taskHeader JSON.parse(JSON.stringify(now))

基于huffman编解码的图像压缩算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 Huffman编码算法步骤 4.2 Huffman编码的数学原理 4.3 基于Huffman编解码的图像压缩 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..…

【操作系统】不同操作系统内核架构分析

一、内核架构与操作系统性能之间的关系的分析 1. 适用性和专业化&#xff1a; 不同的内核架构往往会有不同的设计目标和优化点。例如&#xff0c;实时操作系统&#xff08;RTOS&#xff09;和通用操作系统&#xff08;像Linux或Windows&#xff09;在设计时就有不同的重点&am…

【Python基础011】Python中字符串的具体用法

1、创建 字符串的创建共有3种方式 1&#xff09;单/双引号创建短字符串 s hello worlds “hello world” 2&#xff09;三个单/双引号创建短字符串 三个单/双引号一般用于多行文本的注释&#xff0c;如果将这样的字符串用print打印&#xff0c;或者赋给一个变量&#xff0c;…

3D游戏角色建模纹理贴图处理

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 在本文中&#xff0c;我们将介绍 3D 纹理的基础知识&#xff0c;并讨…

【C语言】数据结构——排序二(快排)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——数据结构学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a;数组打印与交换1. 交换排序1.1 基本思想&#xff1a;1.2 冒泡与快排的异同 2. 冒泡排序2.1 基本思想2.2 …

【Unity动画系统】Animator有限状态机参数详解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

校园跑腿小程序源码系统:取快递+寄快递+食堂超市跑腿 带完整的搭建教程

现如今&#xff0c;越来越多的校园生活服务需求涌现出来。为了满足学生们的日常需求&#xff0c;校园跑腿小程序应运而生。这款小程序集成了取快递、寄快递、食堂超市跑腿等功能&#xff0c;为学生们提供了一个方便、快捷的生活服务平台。 以下是部分代码的示例&#xff1a; 系…