ID: 35579 Updated by: [EMAIL PROTECTED] Reported By: al dot the dot x at gmail dot com -Status: Open +Status: Closed Bug Type: Documentation problem Operating System: ANY PHP Version: Irrelevant -Assigned To: +Assigned To: colder New Comment:
This bug has been fixed in the documentation's XML sources. Since the online and downloadable versions of the documentation need some time to get updated, we would like to ask you to be a bit patient. Thank you for the report, and for helping us make our documentation better. Previous Comments: ------------------------------------------------------------------------ [2005-12-15 16:43:33] [EMAIL PROTECTED] Well, as a second though, I would agree that the manual isn't clear enough. "References inside the array/object you are serialize()ing will also be stored." $a = 'first'; $b = array(&$a); $c = serialize($b); unset($b); $b = unserialize($c); $a = 'second'; echo $b[0]; // -> first, which is not the behavior somebody would expect ------------------------------------------------------------------------ [2005-12-15 16:28:28] [EMAIL PROTECTED] 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' ------------------------------------------------------------------------ [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] [EMAIL PROTECTED] 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 cool. // Reference is not preserved. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=35579&edit=1