note 55766 added to language.references

From: 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

« previous php.notes (#93508) next »