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.