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就会出现
当然也可以在里面写一些其他的代码,这里就不过多赘述了。