网络编程
位置:首页>> 网络编程>> php编程>> php反序列化之魔术方法超详细讲解

php反序列化之魔术方法超详细讲解

作者:隐形卟  发布时间:2023-11-16 07:24:59 

标签:php,反序列化,魔术方法

php魔术方法

在php类保留方法中以 “__”两个下划线开头的函数称为魔术方法,我的理解为php类设计中自定义好的函数。

常见的魔术方法有:

__construct(),类的构造函数
__destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用
__clone(),当对象复制完成时调用
__autoload(),尝试加载未定义的类
__debugInfo(),打印所需调试信息

__construct()与__destruct()

__construct() 构造函数与 __destruct() 析构函数,与其他的语言如java,c#,一样,构造函数就是在对象实例化的时候先执行初始化的方法。

__construct()构造函数只有在new 一个对象的时候会触发,在serialize 序列化和unserialize反序列化中都不会触发

<?php
class demo1{
   private $k1;
   public function __construct()
   {
       echo("构造函数被调用"."<br>");
   }
   public  function f1(){
       echo("f1 函数被调用");
   }
}
echo("0000"."<br>");
$f=new demo1();
echo("1111"."<br>");
$a=serialize($f);
echo("2222"."<br>");
unserialize($a);
?>

输出结果

php反序列化之魔术方法超详细讲解

__destruct() 析构函数则在对象销毁和serialize 反序列化的情况下会被触发。如下

<?php
class demo1{
   private $k1;
   public function __destruct()
   {
       echo("析构函数被调用"."<br>");
   }
}
$f=new demo1();
echo("0000"."<br>");
$a=serialize($f);
echo("1111"."<br>");
unset($f);
echo("2222"."<br>");
unserialize($a);
?>

输出结果

php反序列化之魔术方法超详细讲解

__call

__call 魔术方法的作用是当前对象调用一个不存在的方法时,就会被触发

<?php
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
 //当调用不存在的方法时,方法名作为参数传到$name 变量,方法名的输入参数传到arguments参数列表中
   public function __call($name, $arguments)
   {
       // TODO: Implement __call() method.
       echo($name."---".$arguments[0]);
   }
}
$f=new demo1();
$f->f2("123");//调用不存在的方法f2()
?>

输出结果

php反序列化之魔术方法超详细讲解

__get

__get() 魔术方法是当访问一个对象不存在的变量时就会被触发

<?php
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __get($name)//不存在的变量k会以参数传到$name
   {
       echo($name);
   }
}
$f=new demo1();
$f->k;//不存在的变量k
?>

输出结果

php反序列化之魔术方法超详细讲解

__set

__set() 魔术方法是当给一个对象不存在的变量赋值时就会被触发

<?php
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __set($name, $value)
   {
       echo($name."---".$value);
   }
}
$f=new demo1();
$f->k=123; //给不存在的成员变量赋值
?>

输出结果

php反序列化之魔术方法超详细讲解

__isset

当对不可访问属性调用isset()或empty()时会触发,例如访问类的私有属性,类不存在的成员属性

<?php
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __isset($name)
   {
      echo($name);
   }
}
$f=new demo1();
$f2=unserialize(serialize($f));//反序列化
isset($f2->k1);//使用isset方法判断私有成员属性k1
empty($f2->k1);//使用empty方法判断私有成员属性k1
?>

输出结果

php反序列化之魔术方法超详细讲解

__unset

当尝试使用unset() 销毁函数去销毁一个不可访问的成员属性时会触发,不可访问(包括私有成员属性,不存在的成员属性)

<?php
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __unset($name)
   {
       echo($name);
   }
}
$f=new demo1();
$f2=unserialize(serialize($f));//反序列化
unset($f2->k1);//使用unset销毁私有成员属性k1
unset($f2->faaa);//使用unset销毁不存在的成员属性faaa
?>

输出结果

php反序列化之魔术方法超详细讲解

__sleep

当对象被serialize 序列化时触发调用__sleep

<?php
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __sleep()
   {
       echo("在被序列化时被调用");
   }
}
$f=new demo1();
echo("00000"."</br>");
serialize($f);
?>

输出结果

php反序列化之魔术方法超详细讲解

__wakeup

当进行unserialize 反序列化对象时,__wakeup魔术方法会被触发,看起来__wakeup与__sleep 触发条件是相反的

<?php
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __wakeup()
   {
       echo("在被反序列化时被调用");
   }
}
$f=new demo1();
$uz=serialize($f);
echo("00000"."</br>");
unserialize($uz);
?>

输出结果

php反序列化之魔术方法超详细讲解

__toString

如果一个对象类中存在__toString魔术方法,这个对象类被当做字符串进行处理时,就会触发__toString魔术方法,而不会产生错误

<?php
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __toString()
   {
       echo("__toString 被触发了");
       return "";
   }
}
$f=new demo1();
echo($f);
?>

输出结果

php反序列化之魔术方法超详细讲解

__invoke

当一个对象类中存在__invoke魔术方法,这个对象类被当作函数进行调用时,就会触发__invoke魔术方法,而不会产生错误

<?php
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
class demo1{
   private $k1;
   public  function f1(){
       echo("f1 函数被调用");
   }
   public function __invoke()
   {
      echo("__invoke 被触发了");
   }
}
$f=new demo1();
$f();
?>

输出结果

php反序列化之魔术方法超详细讲解

来源:https://blog.csdn.net/qq_42077227/article/details/127540351

0
投稿

猜你喜欢

  • 在网上查了部分资料但是发现粘上去的代码都存在问题,无奈只好自己修改了一下,代码如下: 如下代码能正常运行,都是网上查找资料最后拼凑总结出来的
  • 无头模式添加,可以让selenium模拟登录,进入到后台运行这里以登录打开公司内网下载数据为例,因为涉及私密问题,所以有些地方我们进行覆盖,
  • 在cssrain整理的一个 试题集 中有这么一道题:<SCRIPT LANGUAGE="JavaScript"&g
  • global 属性返回 Boolean 值,指出正则表达式使用的global 标志 (g) 的状态。默认值为 false。只读。rgExp.
  • ASP给图片加水印是需要组件的...常用的有aspjpeg软件和中国人自己开发的wsImage软件,可以上网搜索下载这两个软件,推荐使用咱们
  • 即使MyISAM表格式非常可靠(SQL语句对表做的所有改变在语句返回之前被写下),如果下列任何事件发生,你依然可以获得损坏的表:&m
  • 在SQL Server中进行开发会让你身处险地,并且寻找快速解决方案。我们编辑了前十名关于SQL Server开发的常见问题。对常见的针对表
  • 相信很多人在使用Ajax与后台php页面进行交互的时候都碰到过中文乱码的问题。JSON作为一种轻量级的数据交换格式,备受亲睐,但是用PHP作
  • Postman生成okhttp代码依赖<dependency>         
  • 修改MySQL下的默认mysql数据库的user表,删除所有host为localhost记录,另外添加一些其他记录,重新启动MySQL服务器
  • 近段时间看了一些论坛上面关于分页的ASP程序依然有许多的关注者,但里面只有代码,没有详细的解释,对于初学者来说,这样总是得不到真正的掌握,此
  • 对象Javascript 根本上是和对象相关的。数组是对象。函数是对象。对象是对象。那什么是对象呢?对象是名-值对的集合。名是字符串,值可以
  • 动机: 排序功能让我们页面上的数据显的更人性化,是我们在网站上见过的很普遍的一个功能效果了。以往的自动排序都是用大量的脚本代码来完成的,对一
  • 今天研究了些取access数据库随机记录问题,这是这我自己搜集整理的方法。大家有没有高见,可以告诉我,或者我总结的东东本身有误,也可以帮我修
  • PHP是一种面向对象的编程语言,它允许开发者使用面向对象的编程技术来构建复杂的应用程序。下面是一些关于PHP面向对象编程的讲解:类与对象类是
  • 因AJAX接受数据时服务器默认是采用UTF-8的编码形式进行传送,所以在很多GB2312中文网页中应用AJAX回传数据经常会发生中文乱码。解
  • 那天突然的一个灵感,是针对防盗链的。正常上传的文件,若被人盗链则增加了自己服务器的负担,上次164.cc就因此被挂。然后想想对策,目前各类防
  • 标志是一种简单的工具,就象铁锤,简单实用。如果一种工具功能太多导致其效用减弱,那就让它保持简单。你并不需要一把有太多装饰的精美铁锤。对于象征
  • 之前看到很多人一直都问CSS 中DIV垂直居中的问题,看来对此的需求还不少。现在就把我经验拿出来分享一下,希望大家鼓鼓掌。因为在 CSS 中
  • 第二次遇到FF下正则兼容性问题( 第一次是关于"g"全局标志的,现在网上已有很多相关文章介绍)。以下正则在FF和IE下的
手机版 网络编程 asp之家 www.aspxhome.com