php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #34593 Unintuitive serialization for inherited objects.
Submitted: 2005-09-22 07:00 UTC Modified: 2005-09-22 21:11 UTC
From: ectsue at gmail dot com Assigned:
Status: Closed Package: Feature/Change Request
PHP Version: 5.0.* OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ectsue at gmail dot com
New email:
PHP Version: OS:

 

 [2005-09-22 07:00 UTC] ectsue at gmail dot com
Description:
------------
I believe that the way serialization works for objects 
doesn't make sense.  I have a subclass whose superclass 
contains a private member variable.  Upon serialization, I 
cannot get the private member variable to serialize for the 
subclass (except by using a "NUL class-name NUL member-name" 
string in __sleep()).

Imho, subclasses shouldn't have to know what parts of their 
parent classes to serialize.  I can think of two possible 
solutions to this problem:

1. Have serialize() walk the inheritance tree for the object 
it is serializing.

2. Have some method that will be able to take the output 
from parent::__sleep() and modify it so that it can be 
passed back from the __sleep() method of the subclass so 
that private member variables in the parent can be 
serialized.  (The function I have in mind would do the NUL 
class-name NUL member-name transformation).

Reproduce code:
---------------
class A {
  private $a;
  public function __sleep() { return array('a'); }
  public function getA() { return $this->a; }
  public function setA($a) { $this->a = $a; }
}

class B extends A {
}

$b = new B();
$b->setA(10);
$bSerialized = serialize($b);
$bUnserialized = unserialize($bSerialized);
var_dump($b);
var_dump($bUnserialized);

Expected result:
----------------
object(B)#1 (1) {
  ["a:private"]=>
  int(10)
}
object(B)#1 (1) {
  ["a:private"]=>
  int(10)
}

Actual result:
--------------
object(B)#1 (1) {
  ["a:private"]=>
  int(10)
}
object(B)#2 (2) {
  ["a:private"]=>
  NULL
  ["a"]=>
  NULL
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-09-22 10:45 UTC] helly@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Have a look at interface serializable in 5.1
 [2005-09-22 10:45 UTC] tony2001@php.net
This code (with __sleep() removed) works perfecty fine:

<?php
class A {
  private $a;
  public function getA() { return $this->a; }
  public function setA($a) { $this->a = $a; }
}

class B extends A {
}

$b = new B();
$b->setA(10);
$bSerialized = serialize($b);
$bUnserialized = unserialize($bSerialized);
var_dump($b);
var_dump($bUnserialized);
?>

Is this what you need?
 [2005-09-22 21:10 UTC] ectsue at gmail dot com
tony: In the project that I ran into this problem, I use the 
__sleep method to return only a subset of the member variables 
of the class.  An object of this class can get to be rather 
large and I do not need to serialize everything.  This class 
is occasionally used as a superclass for other classes (this 
is where I ran into the problem).  So, I do need that __sleep 
function.
 [2005-09-22 21:11 UTC] ectsue at gmail dot com
helly: Where can I find documentation about the serializable 
interface?  I tried a whole site search on php.net and 
couldn't find anything of interest.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jul 17 14:04:04 2025 UTC