ID: 6417
Updated by: venaas
Reported By: [EMAIL PROTECTED]
Status: Analyzed
Bug Type: Scripting Engine problem
Operating System: Linux RedHat 6.2
PHP Version: 4.0.6-dev
New Comment:

I would like to see this fixed, it's a serious bug IMO.
Hope this serves as a reminder to someone (:



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

[2001-05-23 18:49:42] [EMAIL PROTECTED]

Resurfacing.

Is there any work being done on this? Or should I put this in the docs? 

If you don't expect it, this bug can create very strange behaviour, for example when 
you have some library function that creates references, it can mix up your script.

This is definitely a bug, and should be fixed a.s.a.p.
The fix is included here!

status -> analyzed (imo it is even critical, this is straight against the principle of 
assigning by value:

[documentation]
>In PHP, variables are always assigned by value. That is to
>say, when you assign an expression to a variable, the
>entire value of the original expression is copied into the
>destination variable. This means, for instance, that after
>assigning one variable's value to another, changing one of
>those variables will have no effect on the other.

)

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

[2001-04-28 15:27:01] [EMAIL PROTECTED]

Reproduced in latest verison

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

[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.
 */     
?>


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



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


-- 
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