note 95319 added to language.references.pass
| From: | randallgirard at hotmail dot com | Date: | Sun, 27 Dec 2009 05:10:39 +0000 |
| Subject: | note 95319 added to language.references.pass | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-164345@lists.php.net to get a copy of this message | ||
Having problems with getting the magic __destructor() on your class to fire when you want it to? Or
looking for a solution so that you can reference your object from more than one place? (for example:
circular references can be a big problem)
Or, maybe you are just confused at whats really going on differently between PHP4 and PHP5
references? Not much, really... However, the fact that PHP5 references all of it's objects may
be a tad bit misleading to a developer, with assumptions they might make that is.
<?php
/*
The magic __destructor() routine is only fired once ALL references to the object have been unset.
Every time you copy the object to another location (with the = assignment operator,) the reference
count is incremented by one (respectively). When you use a reference assignment, both variable
references will point to the same reference which points to the object (rather than two references
pointing to the same object). What does this mean for us? Even though all references to the
reference must now be unset before the singular reference is unset causing the object to destruct:
By setting a value to any of these variables causes the singular reference (which all the other
references point to,) to point elsewhere, reducing the reference count of the object.
Confused still? Yea, it took me quite some time to wrap my head around the hole concept, but
don't worry it's fairly simple once you get the basics! Allow me to demonstrate how to
pass a variable around so that all references point to another reference (below).
Solution: Basically, the idea is to keep the reference count of the object at 1, even though you
have multiple variables somehow pointing to the object. The referenced reference then has a
reference count of 4, or the number of variables which reference to it.
*/
reftest();
function reftest() {
# initialize the object
$obj1 = new foo();
# $obj1 currently points directly to the new object
# NOTE: $obj1 is NOT currently a reference! (even though all objects in PHP 5 are now technically
references, lets forget about this concept for a moment to prevent confusion... Until you understand
this further, pretend that the variable points directly to the object data)
# create a reference
$obj2 =& $obj1;
# $obj1 and $obj2 both point to the same reference which points to an object
# NOTE: $obj1 is NOW a reference!
# pass a reference from a function
$obj3 =& bar($obj2);
# all variables point to the same reference which points to the object, and it should remain this
way so long as references are used properly
# pass a reference through an array
$array = array( 'obj' => &$obj3 );
$obj4 =& $array['obj'];
# pass a reference through an array from a function (note this function does not contain a reference
operator in the declarations)
$array = noref( array( 'obj' => &$obj4 ) );
$obj5 =& $array['obj'];
# unset the $obj1
unset($obj1);
# This is to demonstrate that ALL references to the reference must be destructed, before the
reference is destructed, causing the object to finally be destructed.
print("Destructor should be fired NEXT<br />\r\n");
# set the reference which all variables point to
$obj3 = 'lala';
# Setting the referenced reference to a value (NULL included), causes the reference count of the
object itself to drop to 0, and the destructor is NOW fired!
# $obj2 $obj3 and $obj4 all still point to the same reference which is now set to 'lala'
print("Destructor should have previously fired... Here are the declared vars:<br
/>\r\n");
# output the defined vars
unset($array);
print("<pre>".print_r( get_defined_vars(), true )."</pre>");
}
class foo {
public function __destruct() { print("DESTRUCTED!<br />\r\n"); }
}
# return a reference from function
function &bar( &$obj ) {
return $obj;
}
# return a reference through an array
function noref( array $arr = array() ) {
return array( 'obj' => &$arr['obj'] );
}
?>
----
Server IP: 192.41.40.227
Probable Submitter: 76.167.60.11
----
Manual Page -- http://www.php.net/manual/en/language.references.pass.php
Edit -- https://master.php.net/note/edit/95319
Del: integrated -- https://master.php.net/note/delete/95319/integrated
Del: useless -- https://master.php.net/note/delete/95319/useless
Del: bad code -- https://master.php.net/note/delete/95319/bad+code
Del: spam -- https://master.php.net/note/delete/95319/spam
Del: non-english -- https://master.php.net/note/delete/95319/non-english
Del: in docs -- https://master.php.net/note/delete/95319/in+docs
Del: other reasons-- https://master.php.net/note/delete/95319
Reject -- https://master.php.net/note/reject/95319
Search -- https://master.php.net/manage/user-notes.php