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

 ID:                 55406
 Updated by:         le...@php.net
 Reported by:        chrisstocktonaz at gmail dot com
 Summary:            get_object_vars and array casting when extending
                     ArrayObject
-Status:             Open
+Status:             Not a bug
 Type:               Bug
 Package:            SPL related
 Operating System:   Linux
 PHP Version:        5.4.0alpha3
 Block user comment: N
 Private report:     N

 New Comment:

This is the expected behavior (I think). ArrayObject is complex and doesn't 
work 
as most people would expect. It's hard for me to keep straight sometimes.  You 
need to set the STD_PROP_LIST bit for this to behave the way you are expecting.


Previous Comments:
------------------------------------------------------------------------
[2011-08-12 11:09:39] RQuadling at GMail dot com

Adding ...

 public function __construct (array $input = array(), $flags = 
ArrayObject::STD_PROP_LIST, $iterator_class = 'ArrayIterator') {
  parent::__construct($input, $flags, $iterator_class); 
 }

as the constructor for TestTwo will output ...

array(1) {
  ["TestOne_1"]=>
  int(1)
}
array(1) {
  ["TestOne_1"]=>
  int(1)
}
array(1) {
  ["TestTwo_1"]=>
  int(1)
}
array(1) {
  ["TestTwo_1"]=>
  int(1)
}
array(2) {
  ["TestThree_1"]=>
  int(1)
  ["TestTwo_1"]=>
  int(1)
}
array(2) {
  ["TestThree_1"]=>
  int(1)
  ["TestTwo_1"]=>
  int(1)
}

So, is this a bug?

Dox says ...
"ArrayObject::STD_PROP_LIST 
Properties of the object have their normal functionality when accessed as list 
(var_dump, foreach, etc.)."

So, without this flag (a bitmask) being set, the "properties" aren't accessible 
in the way you think they should be.

------------------------------------------------------------------------
[2011-08-11 20:41:44] chrisstocktonaz at gmail dot com

My expected result had a typo, "TestOne_1" would not exist in testtwo or 
testthree classes. Here is a patch for this:


--- ext/spl/spl_array.c 2011-07-25 04:35:02.000000000 -0700
+++ ext/spl/spl_array.c   2011-08-11 13:38:52.000000000 -0700
@@ -746,7 +746,12 @@
 {
        spl_array_object *intern = 
(spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);

-       return spl_array_get_hash_table(intern, 1 TSRMLS_CC);
+        HashTable *hh = zend_std_get_properties(object TSRMLS_CC);
+        HashTable *ht = spl_array_get_hash_table(intern, 1 TSRMLS_CC);
+
+        zend_hash_merge(hh, ht, NULL, NULL, sizeof(zend_class_entry *), 0);
+
+       return hh;
 } /* }}} */

 static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) 
/* {{{ */

------------------------------------------------------------------------
[2011-08-11 19:59:18] chrisstocktonaz at gmail dot com

Description:
------------
As discussed on internals mailing list here [1], ArrayObject I think is 
overriding 
the get_properties handler in a bit to simple of a way. I think the ArrayObject 
should merge the spl hash with the default handler.

[1] http://news.php.net/php.internals/54508 

Test script:
---------------
--Code
class TestOne {
  public $TestOne_1 = 1;
}

class TestTwo extends ArrayObject {
  public $TestTwo_1 = 1;
}

class TestThree extends TestTwo {
  public $TestThree_1 = 1;
}

$t1 = new TestOne;
var_dump((array) $t1, get_object_vars($t1));

$t2 = new TestTwo;
var_dump((array) $t2, get_object_vars($t2));

$t3 = new TestThree;
var_dump((array) $t3, get_object_vars($t3));

Expected result:
----------------
array(1) {
  ["TestOne_1"]=>
  int(1)
}
array(1) {
  ["TestOne_1"]=>
  int(1)
}

array(0) {
//  TestOne_1
//  TestTwo_1
}
array(0) {
//  TestOne_1
//  TestTwo_1
}

array(0) {
//  TestOne_1
//  TestTwo_1
//  TestThree_1
}
array(0) {
//  TestOne_1
//  TestTwo_1
//  TestThree_1
}

Actual result:
--------------
array(1) {
  ["TestOne_1"]=>
  int(1)
}
array(1) {
  ["TestOne_1"]=>
  int(1)
}

array(0) {
}
array(0) {
}

array(0) {
}
array(0) {
}


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



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

Reply via email to