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: signature.asc
Description: This is a digitally signed message part

Reply via email to