zoukankan      html  css  js  c++  java
  • 序列化与反序列化

    考虑到可读性,数据往往不是以最有效的方式编写,但为了存储或传递数据时更加高效,同时不丢失其类型和结构,可以利用序列化和反序列化函数对数据进行处理。

    序列化

    将特定格式数据转换为可以恢复的字节串序列

    什么时候进行序列化?

    1)数据在网络上传输时

    2)数据保存到文件中时

    (由于序列化返回的是字符串,方便存储于任何地方!)

     

    反序列化

    顾名思义,将序列化得出的字符串恢复为原有格式数据的过程

    什么时候进行反序列化?

    1)程序读取数据的时候

    序列化和反序列化的目的是在不影响数据有效性情况下,更高效地存储和传输数据,使程序更具维护性。

    以前流行的序列化方式是生成XML字符串,目前几乎都是生成JSON格式字符串。除了一般数据的序列化外,很多语言都支持对object的序列化和反序列化。

     

    PHP中的序列化与反序列化

    函数:

    serialize/unserialize

    json_encode/json_decode

     

    序列化

    serialize函数

    serialize函数是标准的序列化函数,会完整地序列化数据,其中可以修改一个子函数__sleep(),只序列化部分数据,忽略其他数据

    __sleep():是一个钩子函数,默认序列化全部属性,可以修改至只序列化部分属性,没有序列化的属性会被忽略。

    示例:

    1.NULL

    NULL被序列化为N!

    2.boolean

    boolean类型数据被序列化为b:

    true序列化为b:1false序列化为b:0

    3.integer

    i:123 // 123的序列化

    4.double

    d:1.5

    5.string

    s:4:”test” // test序列化,4:字符串长度!

    6.数组(array)

    array(“tony”,”wenxin”)

    a:2:{i:0;s:4:”tony”;i=1;s:6:”wenxin”;}// 解释

    a:array2:数组元素个数0,1:数组的下标

     

    序列化示例

    <?php
    class Person
    {
        var $name;   
        var $sex;    
        var $age;    
    
        function __construct($name = "", $sex = "", $age = "") {
            $this->name = $name;
            $this->sex = $sex;
            $this->age = $age;
        }
    
        function say() {
            echo "我的名字叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age . "<br>";
        }
    }
    
    $p1 = new Person("张三", "男", 20);
    
    $p1_string = serialize($p1);    //把一个对象串行化,返一个字符串
    echo $p1_string . "<br>";        //串行化的字符串我们通常不去解析
    
    //将$p1_string存储到文件file.txt中
    file_put_contents('./file.txt', $p1_string);
    
    $p2 = unserialize($p1_string);    //把一个串行化的字符串反串行化形成对象$p2
    $p2->say();
    
    //下面的做法和上面效果一样
    $p3_file = file_get_contents('./file.txt'); //读取文件
    $p3 = unserialize($p3_file); //反序列化
    $p3->say();
    ?>

     

    上例输出结果:

    O:6:”Person”:3:{s:4:”name”;s:4:”张三”;s:3:”sex”;s:2:”男”;s:3:”age”;i:20;}
    我的名字叫:张三 性别:男 我的年龄是:20

     

    反序列化

    unserialize是反序列化函数

    若被序列化的变量是一个对象,在重新构造对象之后,会自动调用wakeup成员函数(如果存在!) wakeup():

    unserialize函数会检查是否存在__wakeup函数,如果存在,会先调用预先准备的函数!

    <?
    class Person
    {
    
        var $name;   
        var $sex;    
        var $age;    
    
        function __construct($name = "", $sex = "", $age = "") {
            $this->name = $name;
            $this->sex = $sex;
            $this->age = $age;
        }
    
        function say() {
            echo "我的名字叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age . "<br>";
        }
    
        //指定串行化时把返回的数组中$name和$age值串行化,忽略没在数组中的属性$sex
        function __sleep() {
            $arr = array("name", "age"); // 此时,属性$sex将被删除!!!
    
            return($arr);
        }
    
        //重新生成对象时,并重新赋值$age为40
        function __wakeup() {
            $this->age = 40;
        }
    }
    
    $p1 = new Person("张三", "男", 20);
    
    //把一个对象串行化,返一个字符串,调用了__sleep()方法,忽略没在数组中的属性$sex
    $p1_string = serialize($p1);
    echo $p1_string . "<br>"; //串行化的字符串我们通常不去解析
    
    $p2 = unserialize($p1_string); //反串行化形成对象$p2重新赋值$age为40
    $p2->say();
    
    ?>

     

    上例输出为:

    O:6:”Person”:2:{s:4:”name”;s:4:”张三”;s:3:”age”;i:20;}
    我的名字叫:张三 性别: 我的年龄是:40

     

    最后

    序列化与反序列化是一种常见的数据处理方式,也是容易出现安全漏洞的步骤,认识序列化对于任何一个开发人员都是一件必要的知识。

  • 相关阅读:
    转战博客园
    C++虐恋:MBCS安装失败导致的四天误工
    Servlet 3.0 新特性详解 (转载)
    数据库连接池proxool的两种使用方式
    java异常处理中的细节
    InvocationTargetException异常的深入研究-servlet的setAttribute与getAttribute
    如果我是一个全栈极客,那么,下一步该怎么走?
    C++基础与提高 001
    用户及文件权限管理
    命令行操作体验
  • 原文地址:https://www.cnblogs.com/eflypro/p/14074658.html
Copyright © 2011-2022 走看看