是否有可能在php中序列化SplEnum

时间:2014-08-04 15:57:11

标签: php spl

是否可以序列化SplEnum?我尝试使用SplEnum,但userialized实例只有默认值。 例如:

class Test extends SplEnum
{
    const __default = self::A;
    const A = 1;
    const B = 2;
}

...

$t = new Test( Test::B );
$s = serialize($t);
$t2 = unserialize($s);

变量$ t2是Test的实例但具有默认值。

2 个答案:

答案 0 :(得分:2)

在反序列化之后没有获得期望值的原因是SplEnum不仅仅是一个regualar PHP类。这是一种黑客行为。该值保存在自己的结构中,而不是在PHP对象本身中,如您所见

方法spl_type_object_new_ex

中的

https://github.com/davidcoallier/SPL_Types/blob/master/spl_type.c

他们创建了一个内部结构“对象”

object = emalloc(sizeof(spl_type_object));

保存值

ZVAL_ZVAL(object->value, *def, 1, 0);

unserialize函数不知道有关此内部对象的内容,也无法更改其值。因此这种特殊的行为。

更新

您可能希望使用强制转换以保留对象的值。在你的情况下,它可能是:

$casted_value = (int) $t;

至少一个整数更容易处理。

更新2

工作序列化的工作示例。

class Test2 extends SplEnum  implements Serializable 
{
    const __default = 1;
    const A = 1;
    const B = 27;
    const C = 31;

    public function serialize() {
            return serialize ((int) $this);
    }

    public function unserialize($serialized) {
        $this->__construct (unserialize($serialized));
    }
}

答案 1 :(得分:0)

这不是特定于SPL的,您根本无法序列化常量,因为它们不是对象的属性。

如果您实施__wake()方法实施Serializable界面,则可以序列化任何常量,如下面的代码所示。

http://de2.php.net/manual/en/language.oop5.magic.php#object.sleep

<?php
class Test extends SplEnum implements Serializable {
    const A = 1;

    public function serialize() {
        return serialize(array('A' => self::A));
    }

    public function unserialize($serialized) {
        // cannot redeclare A when unserializing!
        // This is not SplEnum specific but with every class.
    }
}

$test = new Test;

echo serialize($test);