Returning non-references still allows access to member variables?

From: 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
« previous php.dev (#89765) next »