Returning non-references still allows access to member variables?
| From: | Matthew Bogosian | Date: | Sun, 20 Oct 2002 12:02:21 +0000 |
| Subject: | Returning non-references still allows access to member variables? | ||
| Groups: | php.dev php.general | ||
| Request: | Send a blank email to php-dev+get-89765@lists.php.net to get a copy of this message | ||
Howdy all,
I have stumbled onto a reference behavior I cannot explain. Here's my
problem: I'm trying to return a copy of a member variable. The function
is not declared to return a reference, but it seems as if the user can
override this. Here's a non-object example:
<?php
// Create an array
$array = array('foo', 'bar', 'baz');
// This function merely returns a copy of the array
function testArray()
{
global $array;
return $array;
}
// Grab the return from the function (notice the '&')
$copiedArray = &testArray();
// Modify it
$copiedArray[] = 'quux';
// Print the original and the copy out
echo "=== array ===\n";
var_dump($array);
echo "=== copiedArray ===\n";
var_dump($copiedArray);
?>
Running this yields exactly what you would expect:
=== array ===
array(3) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(3) "baz"
}
=== copiedArray ===
array(4) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(3) "baz"
[3]=>
string(4) "quux"
}
So far, so good. This is as expected (even if the caller tries to use
the '&', he's getting the reference to the copy). Now instead of a
global array, let's try the exact same thing with a member of a global
object:
<?php
// Dummy class
class Test
{
var $array;
}
// Instantiate it
$object = &new Test();
// Create a member that is an array
$object->array = array('baz', 'bar', 'foo');
// Same function as before, only it's returning a member variable
function testObject()
{
global $object;
return $object->array;
}
// Grab the return from the function (notice the '&')
$copiedArray = &testObject();
// Modify it
$copiedArray['lyx'] = 'quux';
// Print the original and the copy out
echo "=== array ===\n";
var_dump($object->array);
echo "=== copiedArray ===\n";
var_dump($copiedArray);
?>
Here, I would expect that the results would be exactly the same
(remember, there are absolutely no references in the declaration of
testObject() or in the body; everything *should* be a copy). Here's what
gets printed when this is run:
=== array ===
array(4) {
[0]=>
string(3) "baz"
[1]=>
string(3) "bar"
[2]=>
string(3) "foo"
["lyx"]=>
string(4) "quux"
}
=== copiedArray ===
array(4) {
[0]=>
string(3) "baz"
[1]=>
string(3) "bar"
[2]=>
string(3) "foo"
["lyx"]=>
string(4) "quux"
}
Whoa! $copiedArray is now a reference for the member variable! But look
what happens if I redefine the function slightly:
function testObject()
{
global $object;
$array = &$object->array;
return $array;
}
Now I get what I expect again ($copiedArray doesn't point to the member
variable after calling testObject()). So what gives? Why is "return
$object->member;" exempt from the return declaration of the function?
This is an interesting "feature". Not very intuitive...I'd call it a
bug. Has anyone else noticed this? The above behavior happens with
scalars (e.g., strings, numbers) too, not just arrays.
By the way, I'm using PHP 4.2.3.
--Matt
--
Please do not sell or give away my information.
Attachment: [application/pgp-signature] This is a digitally signed message part signature.asc
Attachment: [application/pgp-signature] This is a digitally signed message part signature.asc