note 55766 added to language.references
| From: | grayson at uiuc dot edu | Date: | Fri, 12 Aug 2005 15:59:21 +0000 |
| Subject: | note 55766 added to language.references | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-93508@lists.php.net to get a copy of this message | ||
I found a subtle feature of references that caused a bug in one of my PHP applications. In short,
if an object passes one of its members to an external function that takes a reference as an
argument, the external function can turn that member into a reference to an anonymous point in
memory.
Why is this a problem? Later, when you copy the object with $a = $b, the copy and the original
share memory.
Solution: If you want to have a function that uses references to modify a member of your object,
your object should never pass the member to the function directly. It should first make a copy of
the member. Then give that copy to the function. Then copy the new value of that copy in to your
original object member.
Below is some code that can reporoduce the this feature and demonstrate the workaround.
function modify1 ( &$pointer_obj ){
$pointer_obj->property = 'Original Value';
}
function modify2 ( &$pointer_obj ){
$newObj->property = 'Original Value';
$pointer_obj = $newObj;
}
class a {
var $i; # an object with properties
function corrupt1(){
modify1 ($this->i);
}
function doNotCorrupt1(){
$tmpi = $this->i;
modify1 ($tmpi);
$this->i = $tmpi;
}
function corrupt2(){
modify2 ($this->i);
}
function doNotCorrupt2(){
$tmpi = $this->i;
modify2 ($tmpi);
$this->i = $tmpi;
}
}
$functions = array ('corrupt1', 'corrupt2', 'doNotCorrupt1',
'doNotCorrupt2');
foreach ($functions as $func){
$original = new a;
### Load some data in to the orginal with one of the four $functions
$original->$func();
$copy = $original;
$copy->i->property = "Changed after the copy was made.";
echo "\n{$func}: \$original->i->property = '" . $original->i->property
. "'";
}
The script generates output:
corrupt1: $original->i->property = 'Changed after the copy was made.'
corrupt2: $original->i->property = 'Changed after the copy was made.'
doNotCorrupt1: $original->i->property = 'Original Value'
doNotCorrupt2: $original->i->property = 'Original Value'
----
Manual Page -- http://www.php.net/manual/en/language.references.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+55766
Delete: added to the manual -- http://master.php.net/manage/user-notes.php?action=delete+55766&report=yes&reason=added+to+the+manual
Delete: bad code -- http://master.php.net/manage/user-notes.php?action=delete+55766&report=yes&reason=bad+code
Delete: spam -- http://master.php.net/manage/user-notes.php?action=delete+55766&report=yes&reason=spam
Delete: useless -- http://master.php.net/manage/user-notes.php?action=delete+55766&report=yes&reason=useless
Delete: non-english -- http://master.php.net/manage/user-notes.php?action=delete+55766&report=yes&reason=non-english
Delete: other reasons -- http://master.php.net/manage/user-notes.php?action=delete+55766&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+55766&report=yes
Search -- http://master.php.net/manage/user-notes.php