php序列化与反序列化

定义一个类函数

<?php 
class Student{
    public $name = "studentone";
    function getName(){
        return "Ghost";
    }

    function __construct(){//这个construct就是创建对象的时候所执行的函数
        echo "__construct";
        echo "</br>";
    }
}

$s = new Student();
echo $s->getName()."</br>";
?>

输出内容如下

将以上代码序列化

<?php 
class Student{
    public $name = "studentone";
    function getName(){
        return "Ghost";
    }

    function __construct(){//这个construct就是创建对象的时候所执行的函数
        echo "__construct";
        echo "</br>";
    }
}

$s = new Student();
echo $s->getName()."</br>";

//序列化函数
$s_serialize = serialize($s);
print_r($s_serialize)
?>

输入内容如下

 

将内容反序列化

<?php 
class Student{
    public $name = "studentone";
    function getName(){
        return "Ghost";
    }

    function __construct(){//这个construct就是创建对象的时候所执行的函数
        echo "__construct";
        echo "</br>";
    }
}

$s = new Student();
echo $s->getName()."</br>";

$Student = 'O:7:"Student":1:{s:4:"name";s:10:"studentone";}';
$s_unserialize = unserialize($Student);
print_r($s_unserialize);
echo'</br>'

?>

输入内容如下

O:7:"Student":1:{s:4:"name";s:10:"studentone";}   这几项的意思为O代表object,长度为7,Student类,1个字段,s指string,长度为4,字段的字段名称。

我们可以修改上面的反序列化对象

<?php 
class Student{
    public $name = "studentone";
    function getName(){
        return "Ghost";
    }

    function __construct(){//这个construct就是创建函数的时候所执行的函数
        echo "__construct";
        echo "</br>";
    }
}

$s = new Student();
echo $s->getName()."</br>";

$Student = 'O:7:"Student":1:{s:4:"name";s:7:"teacher";}';//将上面的学生一改为现在的老师,并且前面的数值也要改下,不然会报错。
$s_unserialize = unserialize($Student);
print_r($s_unserialize);
echo'</br>'

?>

显示内容如下

 

当我们调用序列化函数(serialize)或者反序列化函数(unserialize)的时候会率先调用魔法方法__wakeup()  就像上面的__construct()魔法方法一样,创建对象的时候会调用。

如果程序员在__wakeup()里,写了读文件或者写文件,我们就可以读取到其他文件信息或者向文件里面写一些信息

代码如下

<?php 
class Student{
    public $name = "studentone";
    function getName(){
        return "Ghost";
    }

    function __wakeup(){//读文件
        echo "__wakeup"."</br>";
        echo $this->name."</br>";
        $myfile = fopen($this->name,'r') or die ("unable to open file");
        echo fread($myfile,filesize($this->name));
        fclose($myfile);
        echo "</br>";
    }


    function __construct(){//这个construct就是创建函数的时候所执行的函数
        echo "__construct";
        echo "</br>";
    }
}


$s = new Student();
echo $s->getName()."</br>";
//序列化函数
// $s_serialize = serialize($s);
// print_r($s_serialize)
//反序列化函数
$Student = 'O:7:"Student":1:{s:4:"name";s:5:"1.txt";}';//这里的1.txt是同目录下的一个文件,内容为1111
$s_unserialize = unserialize($Student);
print_r($s_unserialize);
echo'</br>'
?>

代码执行后内容如下

 

 

 将上面的代码中的1.txt改为2.txt(2.txt为同目录下的另一个文件,内容为2222),其他内容不需要改变,代码执行如下

 

 

 当上面代码中的__wakeup()函数内,函数为写文件的时候,代码如下

<?php 
class Student{
    public $name = "studentone";
    function getName(){
        return "Ghost";
    }

    // function __wakeup(){//读文件
    //     echo "__wakeup"."</br>";
    //     echo $this->name."</br>";
    //     $myfile = fopen($this->name,'r') or die ("unable to open file");
    //     echo fread($myfile,filesize($this->name));
    //     fclose($myfile);
    //     echo "</br>";
    // }

    function __wakeup(){//写文件
        echo "__wakeup"."</br>";
        echo $this->name."</br>";
        $myfile = fopen("111.php",'w') or die ("unable to open file");
        fwrite($myfile,$this->name);
        fclose($myfile);
        echo "</br>";
    }

    function __construct(){//这个construct就是创建函数的时候所执行的函数
        echo "__construct";
        echo "</br>";
    }
}


$s = new Student();
echo $s->getName()."</br>";
//序列化函数
// $s_serialize = serialize($s);
// print_r($s_serialize)
//反序列化函数
$Student = 'O:7:"Student":1:{s:4:"name";s:18:"<?php phpinfo();?>";}';//把这里的内容改变一下,结果会更加明显
$s_unserialize = unserialize($Student);
print_r($s_unserialize);
echo'</br>'
?>

这样就会将<?php phpinfo();?> 写入到了同目录下的111.php文件下,这样访问111.php就会出现

 

 当然也可以在里面写一些其他的代码,这里就不过多赘述了。

 

posted @ 2020-12-24 22:01  漩溺  阅读(151)  评论(0编辑  收藏  举报