|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2005-12-07 09:20 UTC] 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 cool.
// Reference is not preserved.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 19 05:00:02 2025 UTC |
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.