ID: 6417
Updated by: jmoore
Reported By: [EMAIL PROTECTED]
Old-Status: Analyzed
Status: Open
Bug Type: Scripting Engine problem
PHP Version: 4.0.6-dev
Assigned To: 
Comments:

Reproduced in latest verison

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

[2000-08-31 08:54:19] [EMAIL PROTECTED]
Confirmed for 4.0.2.

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

[2000-08-29 12:17:34] [EMAIL PROTECTED]
<?php
/*
        I've discovered some slightly counter-intuitive behaviour
        with references and arrays. I'm not sure whether this is
        actually a bug or a 'feature', but if it is the latter then
        it should be documented as such.

        Consider the following code involving references and integers:
 */

$a = 5;
$b = &$a;
$c = $a;
$c = 10;

echo "(1) a: $a (should be 5)<br>n";

/*
        Here we have created a variable ($a), made a reference to it ($b),
        made a copy of the original variable ($c), changed the copy ($c=10),
        and then printed out the original value.
        
        This is all fine and as expected.

        Now let's try the same thing, but with the addition of arrays:
 */

$A = array();
$A[0] = 5;
$b = &$A[0];
$C = $A;
$C[0] = 10;

echo "(2) A[0]: $A[0] (I expected it to be 5)<br>n";

/*
        Thus, having copied the array $A to $C, we have actually made
        $C[0] *another* reference to the $A[0] (which is also referenced
        by $c). I would have expected $C[0] to have become detached from
        the reference (as in $c = $a in the first example).
        
        Taking out the line '$b = &$A[0]' in the example above yields the
        expected behaviour:
 */

$A = array();
$A[0] = 5;
$C = $A;
$C[0] = 10;

echo "(3) A[0]: $A[0] (expected it to actually be 5 this time)<br>n";

/*
        Q: What's the explanation for all of this?
        
        A: When the Zend Engine constructs a copy of an array/hash, it constructs
        copies of the individual elements by using zval_add_ref (zend_variables.c).
        This simply increases the reference count of the value in question. If
        that value happens to be referenced by more than one name, it has
        the 'is_ref' flag set. However, in the case of copying array elements,
        the values are still _not_ separated if they have 'is_ref' set.
        
        As I mentioned above, I'm not sure whether this is actually the desired
        behaviour or not. In either case, I couldn't find it documented clearly
        anywhere (maybe I didn't look hard enough--if not, sorry in advance!).
        
        Working under the assumption that the behaviour is incorrect (I 
        certainly find it very confusing), I worked out the following fix to
        the issue (assuming my understanding of the Zend Engine is correct):
        
                Instead of using zval_add_ref as the constructor when copying arrays,
                use this:
                
                ZEND_API void zval_add_ref_or_separate(zval **p)
                {
                        if (PZVAL_IS_REF(*p))
                        {
                                SEPARATE_ZVAL(p);
                        } else {
                                zval_add_ref(p);
                        }
                }
        
        Another question is whether there are similar issues with objects? I 
        haven't investigated...

        Note: I haven't included PHP modules/php.ini etc since I'm
fairly sure
        this issue is unrelated to any site-specific setup.
 */     
?>


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



ATTENTION! Do NOT reply to this email!
To reply, use the web interface found at http://bugs.php.net/?id=6417&edit=2


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to