php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #55406 get_object_vars and array casting when extending ArrayObject
Submitted: 2011-08-11 19:59 UTC Modified: 2012-11-16 18:37 UTC
From: chrisstocktonaz at gmail dot com Assigned:
Status: Not a bug Package: SPL related
PHP Version: 5.4.0alpha3 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: chrisstocktonaz at gmail dot com
New email:
PHP Version: OS:

 

 [2011-08-11 19:59 UTC] 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) {
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-08-11 20:41 UTC] 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-12 11:09 UTC] 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.
 [2012-11-16 18:37 UTC] levim@php.net
-Status: Open +Status: Not a bug
 [2012-11-16 18:37 UTC] levim@php.net
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.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 01:01:28 2024 UTC