1

Not sure what the process is for serializing a child class that is implementing the Serializable interface, the parent class no longer retains the data it was once serializing. Is there a step I am missing?

class A { private $aVar = "test"; } class B extends A implements Serializable { private static $bVar = "tset"; public function serialize() { return serialize(self::$bVar); } public function unserialize($serialized) { self::$bVar = unserialize($serialized); } } $s = serialize(new B()); $u = unserialize($s); 
1
  • What I am actually trying to do is create a static variable in the child class, but since serialization does not handle static variables, I was attempting to serialize just this myself; here, i'll go ahead and change that on here now so better reflects the scenario. Maybe the title should be how to serialize a static variable in a child class? Commented Nov 1, 2017 at 12:36

2 Answers 2

1

I think you're a bit confused as to what's happening here, but essentially what you're seeing is incorrectly scoped variables.

  • Public variables, are variables that are visible to all classes
  • Private variables, are variables that are visible only to the class to which they belong.
  • Protected variables, are variables that are visible only to the class to which they belong, and any subclasses.

If you were to make $aVar in Class A protected or public you'd be able to access it in Class B:

You would get the following:

B Object ( [bVar:B:private] => tset [aVar] => test ) 
Sign up to request clarification or add additional context in comments.

1 Comment

but I don't want to access it; if I were to remove the Serializable interface and corresponding the methods, everything is serialized perfectly fine.
0

Serializing a static doesn't really make sense, so I changed that to a non-static in my answer:

You're supposed to implement Serializable in the parent class as well:

class A implements Serializable { public function __construct(private $aVar) {} public function serialize() { return serialize($this->aVar); } public function unserialize($serialized) { $this->aVar = unserialize($serialized); } } class B extends A implements Serializable { public function __construct($aVar, private $bVar) { parent::__construct($aVar); } public function serialize() { return serialize([$this->bVar, parent::serialize()]); } public function unserialize($serialized) { $arr = unserialize($serialized); $this->bVar = $arr[0]; parent::unserialize($arr[1]); } } $obj = new B('aVal', 'bVal'); $ser = serialize($obj); echo $ser . "\n"; var_export(unserialize($ser)); 
C:1:"B":44:{a:2:{i:0;s:4:"bVal";i:1;s:11:"s:4:"aVal";";}} B::__set_state(array( 'aVar' => 'aVal', 'bVar' => 'bVal', )) 

If you can't do that, you will have to use reflection to get and set the value of aVar from B. That's not an elegant solution, though.

And I know this is an old question, but the Serializable interface is deprecated, you should use __serialize() and __unserialize() instead. This work much the same way, just remove the interface, and you don't need to call \serialize()/\unserialize() in your methods. Also, all classes must serialize as arrays:

// in class A: public function __serialize() { return [$this->aVar]; } public function __unserialize($serialized) { list($this->aVar) = $serialized; } // in class B: public function __serialize() { return [$this->bVar, parent::__serialize()]; } public function __unserialize($serialized) { $this->bVar = $serialized[0]; parent::__unserialize($serialized[1]); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.