For Programmers: Free Programming Magazines  


Home > Archive > PHP Documentation > December 2005 > #35579 [Opn]: Serialize / Unserialize Behavior with Objects including References









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author #35579 [Opn]: Serialize / Unserialize Behavior with Objects including References
colder@php.net

2005-12-15, 6:57 pm

ID: 35579
Updated by: colder@php.net
Reported By: al dot the dot x at gmail dot com
Status: Open
Bug Type: Documentation problem
Operating System: ANY
PHP Version: Irrelevant
New Comment:

I fail to see the specific link with objects, nor the dilemnia, because
serialize/unserialize can't keep references at all:

$a = 'first';
$b = &$a; // create a reference
$c = serialize($b);
unset($b); // kill the reference
$b = unserialize($c); // won't restore it, unserialize() doesn't return
a reference.
$a = 'second';
echo $b;
-> 'first'


Previous Comments:
------------------------------------------------------------------------

[2005-12-15 02:29:34] al dot the dot x at gmail dot com

Also, as I've discovered in further testing, even
internal references are not preserved when serialize()
and unserialize() are employed. For instance (mind the
pun, it's tricky):

Sample Code:
============

class A {
var $value = 0;

function A ( $newValue = 0 ) {
$this->value = $newValue;
} // END constructor
} // END class A

class B {
var pointers = array();
vae aliases = array();
// Excuse the misnomers, please...

function B ( $newPointer = false ) {
if (false !== $newPointer)
$this->ponters[] =& $newPointer;
foreach ($pointers as $index => $value)
$this->aliases[$index] =& $pointers[$index];
} // END constructor
} // END class B

$newA = new A('I'm a new A');
$newB = new B(&$newA);
$oldB = unserialize(serialize($newB));
$newA->value = "Now I'm an old A";

// Forgive the PHP5-style syntax below...

echo $newA->value;
// As expected, Output: Now I'm an old A

echo $newB->pointer[0]->value;
// As expected, Output same...

echo $oldB->pointers[0]->value;
// Somewhat expected, but not desired...
// Output: I'm an old A

$oldB->pointers[0]->value = "Also an old A";
echo $oldB->pointers[0]->value;
echo $oldB->aliased[0]->value;
// Nothing as expected or desired...
// Output 1: Also an old A
// Output 2: I'm an old A
// Internal references aren't even preserved... Boo.

------------------------------------------------------------------------

[2005-12-14 13:16:12] sniper@php.net

And write with big letters "references are NOT pointers!" :)

------------------------------------------------------------------------

[2005-12-07 09:20:40] al dot the dot x at gmail dot com

Description:
------------
As discussed in several bug reports and in the
additional comments in the PHP Documentation site
(eventually, with some reading / searching), the
functions serialize() and unserialize() do not restore
references to other objects in PHP 4. As that this
behavior is unexpected _and_ intrinsic to the use of
session data in PHP, please consider including a caveat
or clarification in the documentation XML for the
affected functions, the "Classes and Objects" section,
and the "Session-Handling Functions" section.

Certainly, there's a workaround with __sleep() and
__wakeup(), but this really needs to be addressed in the
primary documentation in all these places, since the
thread regarding that behavior is now buried among
others and only appears on the description of
serialize().

I also understand that this has been fixed as of PHP 5,
but that's not a very helpful explanation, Most hosting
providers currently run PHP 4.3.x or 4.4.x and place low
priority on upgrading until the next major Apache
version is released (maybe not even then, the slackers).

Reproduce code:
---------------
// Consider:

class dataObject {
var $data = NULL;
var $pointer = NULL;

function dataObject ($newData = false) {
if ($newData !== false) $this->data = $newData;
} // END constructor

function setPointer (&$newPtr) {
return ($this->pointer =& $newPtr);
} // END setPointer

} // END class dataObject

$A = new base('This is A');
$B = new base('This is B');
$A->setPointer(&$B);
$C = serialize($A);

// Now check the original for reference...

$B->data = "Still B, but different";
echo $A->pointer->data; // Funky syntax, I know...

// Output as expected: "Still B, but different"
// But do the same on the serialized version...

unset($A);
$A = unserialize($C);
$B->data = "Where's B now?";
echo $A->pointer->data;

// Output is old "This is B"... Not .
// Reference is not preserved.



------------------------------------------------------------------------


--
Edit this bug report at http://bugs.php.net/?id=35579&edit=1
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com