对象序列化/反序列化是如何工作的?

7
我正在阅读关于 PHP 的序列化/反序列化概念。我在想它们是如何存储在文件系统/数据库中的。我猜测它是以二进制格式存储的。但是,我想知道整个类是如何存储的?我明白数据成员中的数据可以被存储,但是方法是如何存储的呢?
我的意思是,PHP 如何知道例如 someFunc() 函数中写了什么代码?
$obj = new ClassName();
$obj->someFunc();
$serial = serialize($obj);
$unserialobj = unserialize($serial);
$unserialobj->someFunc();

在第2行,PHP可以知道要做什么,但是它如何知道在第5行(一个非序列化对象)要做什么?它是否也保存代码?


3
serialize() 方法不会在任何地方存储任何内容,它只是将一个对象序列化,并将结果作为字符串返回。 - BoltClock
3个回答

11

当对一个对象进行序列化时,PHP只会存储该对象的当前状态,即其属性值。它不会序列化它的方法。相应的类需要在反序列化时加载到内存中。PHP将从序列化字符串中恢复对象的状态,并从同名的类中获取其余的信息(结构和方法)。


请问您能否解释一下“反序列化时相应的类需要在内存中加载”的意思?我该如何做到这一点? - dejjub-AIS
2
@user 只需 include 'my_class.php';。PHP 只需要看到您的类的定义。换句话说,如果您可以执行 new ClassName,那么您就可以反序列化类型为 ClassName 的对象。 - deceze

6

PHP 可以知道在第2行要执行什么,但是它如何知道在第5行(即一个反序列化对象)要执行什么?它会保存代码吗?

是的,serialize() 会保存这个对象所属类及其状态等信息,因此当您反序列化时,您将获得该类的实例,在本例中为 ClassName


0
这是一个简单的例子,用于理解在php中如何序列化反序列化对象。 我们使用序列化将对象转换为字符串,并在其他页面上使用这个对象的当前状态(带有分配的值)进行反序列化。

c.php

<?php class A {
      public $one ;

      public function A($val) {
          $this->one=$val;
         // echo $this->one;
      }

      function display(){
        echo $this->one;
      }

  }
  ?> 

c.php是一个文件,其中包含名为A的类。
a.php

<? 
require_once "c.php";

$ob= new A('by Pankaj Raghuwanshi : Object Searlization.');

$ob->display(); // Output is: by Pankaj Raghuwanshi : Object Searlization.

$s = serialize($ob);

// echo $s will show  a string of an object

?>
<br><A href='b.php?s=<?=$s;?>'>B-file</a>

我们将这个对象序列化并转换为字符串,然后通过get方法传递到另一个页面。
注意:我们可以使用各种方法将此字符串从一个页面传递到另一个页面,例如使用会话(session),将其保存到数据库中并在另一个页面中提取,或者保存到文本文件中。
我们将在另一个名为b.php的文件中反序列化此对象。

b.php

<? 
require_once "c.php";

$ob = unserialize($_GET[s]);
$ob->display();
// Output is: by Pankaj Raghuwanshi : Object Searlization.
?> 

反序列化后,对象表现出与 a.php 文件相同的行为,并且 a.php 的赋值仍然在对象的内存中。如果我们在多个 HTTP 请求之后对此对象进行反序列化,则对象将在其内存中保留所有分配的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接