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

Reply via email to