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

 ID:                 52441
 Comment by:         bastard dot internets at gmail dot com
 Reported by:        bastard dot internets at gmail dot com
 Summary:            Arrays misbehaving with __set() and __get()
 Status:             Open
 Type:               Bug
 Package:            Class/Object related
 Operating System:   WIN
 PHP Version:        Irrelevant
 Block user comment: N

 New Comment:

Der, that last comment was meant to be "Amendment to Result #3".  Ignore
that auto-linked reference to "bug #3"


Previous Comments:
------------------------------------------------------------------------
[2010-07-26 01:36:21] bastard dot internets at gmail dot com

Amendment to bug #3: __set() is bypassed completely, and new arrays can
be freely created within objects if not already protected or private. 
Only if directly setting the array itself (ie "$a->test_array =
array();") will __set() be called.  But not when doing something like
"a$->test_array[] = 'asdf';"

------------------------------------------------------------------------
[2010-07-26 01:19:24] bastard dot internets at gmail dot com

Description:
------------
Mixing __set(), __get(), and protected/private/overloaded properties
that are arrays has unexpected, undocumented, and undesirable results. 
A couple of bugs listed below.  One bug is similar to bug 33941, but the
problem still persists and even more bugs have popped up.

Test script:
---------------
<?php

class A {

    protected $test_array = array('key' => 'test');

      

        function __get($prop) {

                if (!property_exists($this, $prop)) {

                        $this->$prop = null; // just to create it if it didn't 
exist

                        }

                return $this->$prop;

                }

                

    function __set($prop, $val) {

        $this->$prop = $val;

        }

    }



$a = new A();

$a->test_array[] = 'asdf';



?>

Expected result:
----------------
New key/value "0=>'asdf'" assigned to protected class property array
'$test_array'.  If the property didn't yet exist and overloading is
attempted, just create the new '$test_array' property as an array as
intended.  Working with arrays in this manner should work exactly like
with any other variable type.

Actual result:
--------------
Depending on how the above test script is slightly tweaked, a few bugs
pop up.  The focus here is on what happens with line "$a->test_array[] =
'asdf';"





1) If $test_array did *not* previously exist, "Notice: Indirect
modification of overloaded property A::$test_array has no effect in
...test.php on line 18".  This *should've* worked fine.



2) If __set() was *not* declared, "Notice: Indirect modification of
overloaded property A::$test_array has no effect in ...test.php on line
18".  This *should've* resulted in fatal "cannot access protected
property" error.



3) If $test_array did *not* previously exist and __get() was *not*
declared, it will work fine.  __get() *should've* never factored in
here, and $test_array *should've* updated even if already declared
private/protected.



4) If __get() was *not* declared, "PHP Fatal error:  Cannot access
protected property A::$test_array".   __get() *should've* never factored
in here.  If the '[]' compound operator is what's causing this, then
__get() should return a copy of the array with new or existing index if
provided to be processed through __set() as expected.



5) If $test_array was public, it will work fine, bypassing __get() and
__set() as intended.  No bug here.



6) If __get() was declared to return a reference to the property (ie
function &__get($prop){}), it will work fine and bypass __set().  Not a
bug, but this workaround may cause other problems if expecting to
process updates through __set() or wanting just a copy of any other
property returned by __get().


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



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

Reply via email to