【问题标题】:Does PHP serialize Object Methods?PHP 是否序列化对象方法?
【发布时间】:2011-07-04 11:50:52
【问题描述】:

PHP 参考手册说,当序列化一个对象时,方法不会被保存。 (参见http://www.php.net/manual/en/language.oop5.serialization.php,第 1 段)。

但是,手册中给出的第一个示例显示了一个方法被序列化,然后被反序列化并使用。

这不是矛盾吗?我错过了什么吗?

【问题讨论】:

    标签: php serialization


    【解决方案1】:

    我必须说,在第一个示例中,我没有看到方法在哪里被序列化。序列化时没有方法被序列化,只有类名和属性。如果您查看序列化数据,您可以看到这一点

    $ser = serialize($object);
    var_dump($ser);
    

    您会注意到,没有提到任何方法。但是,如果您反序列化一个对象,它会由类名重新创建。或者换句话说:您将获得一个新对象,但具有您之前序列化的值。

    通常这并不像听起来那么重要,因为通常序列化/非序列化对象的行为应该相同。

    // serialize 
    class A {
      public $a = null;
      public function test () {
        echo "Hello";
      }
    }
    $a = new A;
    echo $a->test(); // "Hello"
    $x = serialize($a);
    
    // unserialize (somewhere else)
    class A {
      public $a = null;
      public function test () {
        echo "World";
      }
    }
    $a = unserialize($x);
    echo $a->test(); // "World"
    

    这里的序列化程序使用了一个“错误”的类,并且输出与预期的不同。只要您确保没有类名冲突,您通常不需要考虑它。

    【讨论】:

    • 感谢 KingCrunch,很棒的解释。在阅读参考手册时,我做了一些不正确的假设。不过,您的解释说明了一切。
    【解决方案2】:

    方法没有序列化,但是对象所属的类是:

    不会保存对象中的方法,只保存类名

    因此,当您反序列化时,您将获得同一类的实例,因此您可以在该未序列化实例上调用方法,因为该方法是类定义的一部分,而不是对象本身的成员。这当然假设您在反序列化时具有完全相同的类定义:

    为了能够 unserialize() 一个对象,需要定义该对象的类。

    【讨论】:

    • 这不是一个全新的实例。只是在序列化时返回到该对象的阶段
    • @Shakti:这是一个新实例。你是对的,那就是重建对象的预序列化状态,但它是在新实例之上重建的。因为(例如)您可以从/向文件读取/写入序列化对象,所以无法在不同调用期间保留实例。 (($a === unserialize(serialize($a))) === false))
    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    相关资源
    最近更新 更多