php反序列化魔术方法

反序列化魔术方法

魔术方法 触发时机
__construct() 在实例化对象时触发
__destruct() 在对象被销毁时触发
__sleep() 在进行序列化时触发
__wakeup() 在进行反序列化时触发
__serialize() 在进行序列化时触发
__unserialize() 在进行反序列化时触发
__toString() 被当成字符串调用时
__invoke() 被当成函数调用时
__set() 给不可访问或者不存在的属性赋值时
__get() 调用不可访问或者不存在的属性的值时
__isset() 对不可访问或不存在的属性调用isset()或empty()时
__unset() 对不可访问或不存在的属性调用unset()时
__call() 调用不可访问的方法时
__callStatic() 在静态上下文中调用一个不可访问的方法时

__construct()

每次实例化一个对象时都会先调用此方法

<?php
class star{
    public function __construct(){
        echo 'gogogo触发喽';
    }
}

$star = new star();//gogogo触发喽

__destruct()

某个对象的所有引用都被删除或当对象被显式销毁时执行

<?php
class Moon{
    function __construct(){
        echo "流萤逐月\n";
    }

    function __destruct(){
        echo "月落乌啼霜满天\n";
    }
}

$moon = new Moon();
//流萤逐月
//月落乌啼霜满天

__sleep()

serialize()函数会检查类中是否存在一个魔术方法__sleep()。如果存在,该方法会先被调用,然后才执行序列化操作

<?php
error_reporting(0);
class Moon{
    public $moon='月亮 ';

    function __construct(){
        echo $this->moon;
    }
    function __sleep(){
        $this -> moon = 'moon';
        echo $this -> moon;
    }
}

$moon = new Moon();//月亮

serialize($moon);//moon

__wakeup()

unserialize()函数会检查类中是否存在一个魔术方法__wakeup()。如果存在,该方法会先被调用,然后才执行序列化操作

<?php
error_reporting(0);
class Moon{
    
    public $moon='月亮';

    function __construct(){
        echo $this->moon;
    }

    function __wakeup(){
        $this -> moon = 'moon';
        echo $this -> moon;
    }
}

$moon = new Moon();//月亮

$tem=serialize($moon);

unserialize($tem);//moon

__serialize()

serialize()函数会检查类中是否存在一个魔术方法__serialize()。如果存在,该方法将在任何序列化之前优先执行,然后才执行序列化操作,它必须以一个代表对象序列化形式的 键/值 成对的关联数组形式来返回,如果没有返回数组,将会抛出一个TypeError错误。 如果类中同时定义了__sleep()__serialize(),则只有__serialize()会被调用,__sleep()方法会被忽略掉

<?php
error_reporting(0);
class Moon{
    public $moon='月亮 ';

    function __construct(){
        echo $this->moon;
    }
    
    function __sleep(){
        $this -> moon = 'moon';
        echo $this -> moon;
    }

    function __serialize(){
        $this -> moon = 'star';
        echo $this -> moon;
    }
}

$moon = new Moon();//月亮

serialize($moon);//star

__unserialize()

unserialize()函数会检查类中是否存在一个魔术方法__unserialize()。如果存在,该方法会先被调用,然后才执行序列化操作,此函数将会传递从__serialize()返回的恢复数组。然后它可以根据需要从该数组中恢复对象的属性。如果类中同时定义了__wakeup()__serialize(),则只有__serialize()会被调用,__wakeup()方法会被忽略掉

<?php
error_reporting(0);
class Moon{

    public $moon='月亮';

    function __construct(){
        echo $this->moon;
    }

    function __wakeup(){
        $this -> moon = 'moon';
        echo $this -> moon;
    }

    function __unserialize(array $data):void{
        $this -> moon = "star";
        echo $this -> moon;
}
}

$moon = new Moon();//月亮

$tem=serialize($moon);

unserialize($tem);//star
<?php
error_reporting(0);
class Moon{
    public $moon;
    public $star;
    public $sun;

    function __serialize():array{
        return [
            'moon'=>$this->moon,
            'star'=>$this->star,
            'sun'=>$this->sun
        ];
    }
    function __unserialize(array $data):void{
        $this->moon = $data['moon'];
        $this->star = $data['star'];
        $this->sun = $data['sun'];
    }
}

__toString()

__toString()方法用于一个类被当成字符串时应怎样回应

<?php
error_reporting(0);
class Moon{

    function __toString(){
        echo "桂魄初生";
}
}

$moon = new Moon();
echo $moon;//桂魄初生

__invoke()

当尝试以调用函数的方式调用一个对象时,__invoke()方法会被自动调用

<?php
error_reporting(0);
class Moon{

    function __invoke(){
        echo "清辉漫瓦";
}
}

$moon = new Moon();
$moon();//清辉漫瓦

__set()

在给不可访问(protected 或 private)或不存在的属性赋值时,__set()会被调用

<?php
error_reporting(0);
class Moon{
    function __set($name,$value){
        echo "玉壶冰心";
    }
}

$moon = new Moon();
$moon-> null = 'null';//玉壶冰心

__get()

读取不可访问(protected 或 private)或不存在的属性的值时,__get()会被调用

<?php
error_reporting(0);
class Moon{
    function __get($star){
        echo "蟾光碎银";
    }
}

$moon = new Moon();
$moon-> null;//蟾光碎银

__isset()

当对不可访问(protected 或 private)或不存在的属性调用 isset()或empty()时,__isset()会被调用

<?php
error_reporting(0);
class Moon{
    function __isset($star){
        echo "素娥垂泪";
    }
}

$moon = new Moon();
isset($moon -> null);//素娥垂泪

__unset()

<?php
error_reporting(0);
class Moon{
    function __unset($star){
        echo "寒璧悬空";
    }
}

$moon = new Moon();
unset($moon -> null);//寒璧悬空

__call()

对象中调用一个不可访问方法时,__call()会被调用

<?php
error_reporting(0);
class Moon{
    function __call($name, $arguments){
        echo "河汉清浅";
    }
}

$moon = new Moon();
$moon -> invalid();//河汉清浅

__callStatic()

在静态上下文中调用一个不可访问方法时,__callStatic()会被调用

<?php
error_reporting(0);
class Moon{
    static function __callStatic($name, $arguments){
        echo "银潢倾泻";
    }
}

$moon = new Moon();
Moon::invalid();//银潢倾泻
posted @ 2025-04-19 14:41  Pr0x1ma  阅读(118)  评论(0)    收藏  举报