面向对象中的序列化和反序列化

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

在PHP中,可以通过serialize()方法序列化,serialize()返回字符串,此字符串包含了表示value的字节流,可以存储于任何地方。

这有利于存储或传递PHP的值,同时不丢失其类型和结构。

想要将已序列化的字符串变回PHP的值,可使用unserialize()方法。serialize()可处理除了resource(资源类型)之外的任何类型。甚至可以serialize()那些包含了指向其自身引用的数组。你正serialize()的数组或对象中的引用也将被存储。

当序列化对象时,PHP将试图在序列动作之前调用该对象的成员函数__sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用unserialize()恢复对象时,讲调用__wakeup()成员方法。

序列化和反序列化的一些基本的解释可以移步到:点击打开链接 查看。

比如我现在链接数据库,链接数据库类的代码可以移步到:点击打开链接 查看。

我这里做一下小小的改变,加入两个魔术方法:

public function __sleep()
    {
        return ['host', 'username', 'password', 'dbName', 'port', 'charset'];
    }

    public function __wakeup()
    {
        $this->mysqlConnect();
    }


由于没有加入到代码片段,这次还是贴出来吧,如下:

class DB {
    private $host; //主机
    private $username; //用户名
    private $password; //密码
    private $dbName; //数据库名称
    private $port; //数据库端口
    private $socket; //套接字
    private $mysqli; //mysqli对象
    private $charset; //字符集
    private $lastSql; //最后执行的sql

    public function __construct($array=[])
    {
        $this->charset = isset($array['charset']) ? $array['charset'] : 'utf8';
        $this->connect($array);
        $this->mysqlConnect();
    }

    public function connect($array=[])
    {
        $this->host = isset($array['host']) ? $array['host'] : '127.0.0.1';
        $this->username = isset($array['username']) ? $array['username'] : 'root';
        $this->password = isset($array['password']) ? $array['password'] : 'root';
        $this->dbName = isset($array['dbName']) ? $array['dbName'] : '';
        $this->port = isset($array['port']) ? $array['port'] : 3306;
        $this->socket = isset($array['socket']) ? $array['socket'] : '';
    }

    private function mysqlConnect()
    {
        $this->mysqli = new mysqli($this->host,$this->username,$this->password,$this->dbName,$this->port);
    }


    public function query($sql)
    {
        $this->lastSql = $sql;
        $result = $this->mysqli->query($this->lastSql);
        if($result === false) {
            $this->error();
        }
        return $result;
    }

    public function Charset($charset='')
    {
        $this->charset = $charset ? $charset: $this->charset;

        $this->execute("set names {$this->charset}");
    }


    public function execute($sql)
    {
        $this->query($sql);
        return true;

    }

    public function select($sql)
    {
        $result = $this->query($sql);
        return $result->fetch_all(MYSQLI_ASSOC);

    }

    public function getLastSql()
    {
        return $this->lastSql;
    }

    public function error()
    {
        $result = '';
        if($this->mysqli->error) {
            $result.= "错误提示:{$this->mysqli->error}<br />";
        }

        if($this->mysqli->errno) {
            $result.= "错误代号:{$this->mysqli->errno}<br />";
        }
        if(!empty($result)){
            $result.="错误的sql语句:{$this->lastSql}";
        }

        if(!empty($result)) {
            exit($result);
        } else {
            exit('没有错误');
        }
    }

    public function __sleep()
    {
        return ['host', 'username', 'password', 'dbName', 'port', 'charset'];
    }

    public function __wakeup()
    {
        $this->mysqlConnect();
    }
}

我现在实例化类,然后查询,然后如果我想把这个类传递到其他地方,其他地方拿起来就可以直接用,而不用再去实例化时候该怎么办呢?

我new一个对象出来,然后将它序列化:

$db1 = new DB(['dbName'=>'test']);
var_dump($db1->select('select * from test limit 1,3'));
$str = serialize($db1);


结果如下:



假如我这个$str,传递到我其他的页面,怎么办传递? session,cookie,文件,数据库都可以传递,我在另外的一个页面,将这个字符串反序列化:

$str = $_SESSION['str'];

$str = serialize($db1);

$db2 = unserialize($str);

var_dump($db2->select('select * from test limit 1,4'));

然后我们再看看结果:


哈哈,我们又链接成功了,主要是我们在__wakeup()方法里面做了链接操作,在这个类被反序列化的时候,就自动连上了。

不过有一点要注意,反序列化成对象的时候,其实和序列化时候的类已经不是同一个类了,我var_dump两个对象,可以看出来



对象编号已经改变了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 序列化是指将对象转换为可以存储或传输的格式,而反序列化是将序列化的对象重新转换为原始对象。 在计算机科学,对象通常是存储在内存的数据结构。当我们需要将这些对象保存到硬盘上或者通过网络传输时,就需要将其序列化序列化过程将对象的状态转换为字节流,这样就可以将其保存到文件或者通过网络传输。序列化可以实现数据的长期保存和远程传输。 反序列化序列化的逆过程。通过读取存储在文件或网络的字节流,反序列化可以将其还原为原始的对象。反序列化操作可以在不同的计算机或进程之间进行,从而实现对象的共享和数据传输。 序列化反序列化在许多应用非常重要。例如,在分布式系统,可以通过将对象序列化反序列化来传输数据和状态。在面向对象的数据库,对象的序列化反序列化可以实现数据的持久化和恢复。此外,序列化反序列化还可以用于远程方法调用、缓存和对象传递等方面。 总之,序列化反序列化是将对象在不同环境的存储和传输的过程。序列化将对象转换为字节流,而反序列化则将字节流还原为原始的对象。这两个过程在许多计算机应用起着重要的作用。 ### 回答2: 序列化是将对象转换为字节流的过程,可以将对象在网络传输、持久化存储以及分布式计算等场景进行传输和存储。反序列化则是将字节流转换为对象的过程,将序列化后的字节流重新转化为原始的Java对象。 在序列化过程,对象的状态信息包括实例变量的值、类名称以及对象的元数据等都会被保存到字节流。这个字节流可以用于保存到文件或者通过网络传输给其他系统。序列化的作用是可以将对象的状态信息进行持久化存储,即使程序结束后再次开始时也能够恢复之前的状态。 而反序列化是将字节流转化为对象的过程。这个过程需要根据序列化的规则和定义来进行,即反序列化的过程需要与序列化时使用的规则和定义相对应。当需要从文件或者其他系统恢复之前序列化的对象时,就需要进行反序列化操作。 在Java,可以通过实现Serializable接口来指示该类可以被序列化Serializable接口是一个标记接口,没有定义任何方法,但是当一个类实现了Serializable接口后,就代表这个类的对象可以被序列化反序列化。 总的来说,序列化反序列化是一种将对象转换为字节流和将字节流转换为对象的机制。通过序列化,对象的状态信息可以进行持久化的存储和传输,在需要时可以通过反序列化将对象的状态信息重新恢复。 ### 回答3: 序列化反序列化是编程常用到的两个概念。序列化是将数据在内存的对象转化为可存储或传输的格式,而反序列化则是将已序列化的数据还原为内存的对象。 在使用序列化时,可以将对象转化为字节流、XML文档或JSON字符串等形式,以便于保存到文件、数据库或在网络传输。序列化的过程将对象的状态信息保存下来,包括对象的字段值、属性值以及相关的类信息,从而可以在需要时重新创建对象。 反序列化则是将序列化后的数据重新还原为原来的对象。通过反序列化,可以恢复对象在序列化前的状态,从而可以继续使用、传输或持久化存储。 序列化反序列化的应用场景很多,比如在分布式系统,可以将对象序列化后使用网络传输,实现不同进程或不同机器之间的通信。另外,在持久化存储方面,可以将对象序列化后保存到磁盘或数据库,以便下次使用时快速还原对象。 在Java序列化反序列化可以通过实现Serializable接口来完成。对于其他编程语言,也通常提供了类似的序列化机制。 总之,序列化反序列化是编程重要的概念,可以方便地在不同环境传输、保存和还原对象,提升程序的灵活性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值