ID: 17419 Updated by: [EMAIL PROTECTED] Reported By: wdseelig at ncms dot org -Status: Open +Status: Closed Bug Type: Documentation problem Operating System: BSDi PHP Version: 4.2.1 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. "Some types of data can not be serialized thus stored in sessions. It includes resource variables or objects with circular references (i.e. objects which passes a reference to itself to another object)." Previous Comments: ------------------------------------------------------------------------ [2003-01-04 12:08:08] wdseelig at ncms dot org My apologies for taking so long to respond. The Christmas season intervened. Here is an answer to the question: THE BASICS A circular reference occurrs when an object passes a reference to itself to another object. Imagine a script in which an object of one class instantiates an object of another class. Call the first object the "parent" and the second object the "child". What happens if the parent object passes a reference to itself to the child object? Could the child object then use this reference to access the methods and properties of the parent object? The code would look something like this: <? class Parent { var $childvar; var $parentvar; function Parent() { $this->childvar =& new Child(&$this); $this->parentvar = 22; } } class Child { var $parentcall; function Child(&$par) { $this->parentcall = &$par; } function getparentvar() { print("<br>The value of the parent variable from within the child is" . $this->parentcall->parentvar; } } >? Note that the parent passes a reference to itself to the child which then stores this reference in a variable called $parentcall. When the child function getparentvar is called, the child uses the stored reference to its parent to access a property ($parentvar) of the parent. Will this work? The answer is yes, BUT. The "yes" is that if you run this code it will work fine. The "BUT" is that if you ask PHP's serializer to reconstruct this structure, it will NOT work. What happens, in other words, if you add to the above script code that looks like this: <? if ( ! session_is_registered("sess") )// Create a session variable to store parent and child { session_register("sess"); $sess = new Parent(); } print ("The vaue of parentvar from within the child is: " . $sess->childvar->getparentvar()); ?> Answer: the the first time that you run this, it will work fine. HOWEVER, if you try to refresh your browser screen, PHP uses its seralizer to reconstruct the $sess variable and is unable to do so. As a consequence, you will get error messages, and, in some cases, PHP will crash. The reason is that the serializer considers this structure to be a circular reference [the child class is referencing the parent] and is not able to handle such constructs. A FURTHER EXPLANATION Why would one try to create a Parent/Child structure like that outline above? Perhaps a brief explanation of what I was trying to do will shed further light on the issue. In my case, the "parent" class was a page manager, and was responsible for sending html to the browser. The child classes were a connection manager and a recordset manager. I wanted all of the classes: the page manager, the connection manager, and the recordset manager, to have access to a set of common error handling routines. So, in my first attempt, I included all of the error handling machinery in the page manager class, and passed a reference to the page manager class down to the connection and recordset manager classes. [Much like the Parent/Child code above]. When this didn't work, I removed the error handling code from the page manager class, and created a new error handling class. However, I did not want each object to insantiate its own error object, so I was still confronted with the problem of letting the recordset and connection objects know where the error object was. The solution to this dilemma was to instantiate error, recordset manager, and connection objects in the page manager, and then pass a reference to the error object to both the recordset and the connection objects. Now this may seem like exactly the same kind of thing that got me in trouble in the first place, but it is not. In this case, the reference that is being passed is NOT a reference to the parent, but rather it is a reference to another child object--and this, for some reason, works just fine. I don't know how clear this is; if you would like to ask me questions, please feel free to do so. Wyckham Seelig ------------------------------------------------------------------------ [2002-12-13 11:02:51] [EMAIL PROTECTED] This one is related too: http://bugs.php.net/bug.php?id=14645 ------------------------------------------------------------------------ [2002-12-13 11:01:15] [EMAIL PROTECTED] Please further explain what circular references are so this can be documented. ------------------------------------------------------------------------ [2002-06-01 07:12:14] [EMAIL PROTECTED] Reclassified as a documentation problem after a nice discussion with Markus :) ------------------------------------------------------------------------ [2002-06-01 07:03:28] [EMAIL PROTECTED] Suspending. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/17419 -- Edit this bug report at http://bugs.php.net/?id=17419&edit=1