零基础入门——从零开始学习PHP反序列化笔记(二)

魔术方法

魔术方法介绍

__construct()

触发时机:实例化对象之前

构造函数,在实例化一个对象的时候,首先会去自动执行的一个方法;

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

?>

__destruct()

触发时机:实例化对象结束后执行 反序列化过程中触发

析构函数,在对象的所有引用被删除或者当对象被显式销毁时执行的魔术方法。

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

__sleep()

触发时机:序列化serialize之前

序列化serialize()函数会检查类中是否存在一个魔术方法__sleep().
如果存在,该方法会先被调用,然后才执行序列化操作。
此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。
如果该方法未返回任何内容,则NULL被序列化,并产生一个E_NOTICE级别的错误。

image-20230430155606920echo serialize($user);?>N;

<?php
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);
?>

可以看到 调用sleep()方法之后 password并没有被回显

例题

payload

http://192.168.20.158:8000/class08/2.php?benben='id'

__wakeup()

触发时机:反序列化unserialize之前

例题

payload

http://192.168.20.158:8000/class08/4.php?benben=O:4:"User":1:{s:8:"username";s:2:"id";}

__tostring()

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

代码示例

__invoke()

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

代码示例

__call()

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

__callStatic()

触发时机:静态调用或调用成员常量时使用的方法不存在

__get()

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

__set()

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

__isset()

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

__unset()

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

__clone()

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

触发时机归纳

posted @ 2023-07-18 16:26  Tzyyyyy  阅读(50)  评论(0编辑  收藏  举报