ID:               20065
 User updated by:  [EMAIL PROTECTED]
 Reported By:      [EMAIL PROTECTED]
-Status:           Open
+Status:           Closed
 Bug Type:         Scripting Engine problem
 Operating System: GNU/Linux 2.4.18-17.7.x (RedHat)
 PHP Version:      4.2.3
 Assigned To:      john
 New Comment:

Oops...I didn't mean to re-open this bug...just to add a comment.


Previous Comments:
------------------------------------------------------------------------

[2002-12-01 21:43:53] [EMAIL PROTECTED]

I'll have to take your word for it, but I still can't understand how
this is supposed to be "expected" or correct:

    <?php

    // Dummy class
    class Test
    {
        var $myString;
    }

    // Instantiate it
    $object = &new Test();
    // Initialize the member
    $object->myString = 'hello';

    // Test function
    function testObject()
    {
        global $object;

        // Make a copy of the member variable (no '&')
        $newString = $object->myString;

        // Return the COPY
        return $newString;
    }

    // Grab the return from the function (notice the '&')
    $copiedString = &testObject();
    // Modify it
    $copiedString = 'goodbye';

    // Print the original and the copy out
    echo "=== array ===\n";
    echo $object->myString . "\n";

    ?>

Outputs:

    === array ===
    goodbye

If this is "expected", I'd suggest the engine was broken. I can't see
how this would make any sense in any kind of language definition. Maybe
it really is a "won't fix" (i.e., it's too difficult a bug to fix
without a rewrite, or people will just have to use the work-around),
but I'm almost positive this is not the correct behavior.

Just out of curiosity, does Zend maintain its own bug database? If so,
is this a duplicate (i.e., do they already know about his problem)?

------------------------------------------------------------------------

[2002-12-01 16:53:52] [EMAIL PROTECTED]

Just discussed this with some other PHP guys; this is "expected"
behaviour (if you know how the engine works), and will not be fixed.

------------------------------------------------------------------------

[2002-12-01 16:38:27] [EMAIL PROTECTED]

array is a reserved word; it is usually ok to have reserved words as
variable names but should be avoided.

Now, the other thing is that "&" is a symbol table alias operator (not
an address-of operator).  So is the "global" keyword, mixing it with
the "&" operator is going to lead to confusion.
(In other words, make sure you *really* know what is happening here!)

Have you tried doing the same thing but using
$GLOBALS["array"] ?


------------------------------------------------------------------------

[2002-12-01 15:14:16] [EMAIL PROTECTED]

Very strange... 

return $object->array; 

should return a copy of the member variable $array, not a reference.
This is of course assuming the function isn't designed to return a
reference (denoted by a & in the function declaration)... You note
that

$foo = &$object->array; 
return $foo


Which leads me to believe this is actually a real bug and not a
"feature"... Hence I'm changing the status to Verified

When I get a moment I'm going to investigate this a little bit, but it
wouldn't surprise me to see this cleaned up in ZE2.

------------------------------------------------------------------------

[2002-10-24 13:22:12] [EMAIL PROTECTED]

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.

Now for something REALLY weird. Check this out:

    <?php

    // Dummy class
    class Test
    {
        var $myString;
    }

    // Instantiate it
    $object = &new Test();
    // Create a member
    $object->myString = 'hello';

    // Test function
    function testObject()
    {
        global $object;

        // Make a copy of the member variable (no '&')
        $newString = $object->myString;

        // Return the COPY
        return $newString;
    }

    // Grab the return from the function (notice the '&')
    $copiedString = &testObject();
    // Modify it
    $copiedString = 'goodbye';

    // Print the original and the copy out
    echo "=== array ===\n";
    echo $object->myString . "\n";

    ?>

Here's the output:

    === array ===
    goodbye

Huh?! I even made a copy inside the function! Note that just as before
(see original message), the following change "fixes" things:

    function testObject()
    {
        global $object;

        // Create a reference to the member variable
        $newString = &$object->myString;

        // Return the reference
        return $newString;
    }

Now the output is as expected(?):

    === array ===
    hello

So (at least according to these tests) it seems that reference handling
of object data members is somewhat inconsistent with the rest of the
world (and of the PHP language specification, from what I understand).

------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=20065&edit=1

Reply via email to