php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68682 RecursiveIteratorIterator does not recurse
Submitted: 2014-12-29 10:08 UTC Modified: 2017-12-22 17:36 UTC
Votes:3
Avg. Score:3.0 ± 1.6
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: spinkus at epicmorsel dot com Assigned:
Status: Not a bug Package: SPL related
PHP Version: 5.4.35 OS: Linux
Private report: No CVE-ID: None
 [2014-12-29 10:08 UTC] spinkus at epicmorsel dot com
Description:
------------
RecursiveIteratorIterator fails to Recurse into class implementing iteratorAggregate and returning RecursiveArrayIterator on private data. See test script.

Test script:
---------------
class X implements IteratorAggregate {
  private $data = ['X', 'X', 'X'];
  # public $data = ['X', 'X', 'X'];
  
  public function __construct($data = null) {
    $this->data = isset($data) ? $data : $this->data;
  }
  
  public function getIterator() {
    return new RecursiveArrayIterator($this->data);
  }
}

$x = new X([1, 2, new X(), 5]);
$it = new RecursiveIteratorIterator($x);
foreach($it as $v) {
  var_dump($v);
}

Expected result:
----------------
Expecting no difference between public and private data. RecursiveArrayIterator should make a copy of the private data on construction.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-12-29 10:31 UTC] spinkus at epicmorsel dot com
-PHP Version: 5.4.36 +PHP Version: 5.4.35
 [2014-12-29 10:31 UTC] spinkus at epicmorsel dot com
Hmm, just realised it's probably more likely RecursiveIteratorIterator is treating the object in the array [1,2, new X(), 5] as an object and iterating its public fields. Investigating.
 [2014-12-29 10:35 UTC] spinkus at epicmorsel dot com
Confirmed. In example data `[1, 2, new X(), 5]`, the getIterator() method of the X instance is never called.
 [2017-12-22 17:36 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2017-12-22 17:36 UTC] nikic@php.net
As you already noticed yourself, RecursiveArrayIterator (despite the "array" in the name) also iterates over object properties. As such, the observed behavior is "expected". You can specify the CHILD_ARRAYS_ONLY flag to not iterate public properties, but in that case the object will not recurse at all. There is no option to recurse based on getIterator().
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Wed Apr 21 04:01:24 2021 UTC