php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #62810 IteratorIterator changes the class of the inner iterator, breaking some calls
Submitted: 2012-08-13 15:57 UTC Modified: 2012-08-30 22:51 UTC
From: burke dot cates at gmail dot com Assigned: tyrael (profile)
Status: Closed Package: SPL related
PHP Version: 5.4.5 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: burke dot cates at gmail dot com
New email:
PHP Version: OS:

 

 [2012-08-13 15:57 UTC] burke dot cates at gmail dot com
Description:
------------
in case the test script is unreadable, https://gist.github.com/3341836 .

I have a class, A, that implements SeekableIterator, Countable in my codebase 
that defines all the required methods (count(), next(), seek(), valid(), 
current(), key()). When I have an instance of this class, $a, and construct a 
new IteratorIterator-extending class, B with instance $b, by passing in $a to 
B's constructor, a call to $b->count(), for example, will fail if A::count() is 
defined to use any fields also defined in A.

 An example is shown in my test script by simply extending ArrayIterator for the 
sake of simplicity. I override its count() method to echo the $extra field. The 
"Notice" line in the output shows that PHP is attempting to find $extra in B 
($b), but it is not there since B is defined as an extension of 
IteratorIterator. This only happens when calls are going through the 
IteratorIterator, as a var_dump($b->getInnerIterator()) show that the 
innerIterator is the proper class.

I tried to figure out why this is happening on my own, so I started looking 
through the spl_iterators.c code to figure out why this is happening. I ended up 
at Line 1534[1], which shows the ce of the inner getting set to the ce of the 
object being initialized.

[1] spl_iterators.c, line 1534 :
https://github.com/php/php-src/blob/master/ext/spl/spl_iterators.c#L1534

Test script:
---------------
class A extends ArrayIterator {
	private $extra;
	public function __construct($extra) {
		$this->extra = $extra;
		parent::__construct(array(1,2,3,4,5));
	}

	public function count() {
		var_dump($this);
		echo "extra: {$this->extra}\n";
		return 5;
	}
}

class b extends IteratorIterator {
}

$a = new A("not gonna see this");
$b = new B($a);

echo "A: ";
$a->count();
echo "\n\nB: ";
$b->count();

Expected result:
----------------
A: object(A)#1 (2) {
  ["extra":"A":private]=>
  string(18) "not gonna see this"
  ["storage":"ArrayIterator":private]=>
  array(5) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
    [3]=>
    int(4)
    [4]=>
    int(5)
  }
}
extra: not gonna see this


B: object(b)#2 (0) {
*not really sure what this should look like*
}
extra: not gonna see this

Actual result:
--------------
A: object(A)#1 (2) {
  ["extra":"A":private]=>
  string(18) "not gonna see this"
  ["storage":"ArrayIterator":private]=>
  array(5) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
    [3]=>
    int(4)
    [4]=>
    int(5)
  }
}
extra: not gonna see this

B: object(b)#2 (0) {
}
Notice: Undefined property: b::$extra in /root/blankdir/test.php on line 12
extra: 


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-08-17 16:16 UTC] burke dot cates at gmail dot com
I forgot the password for this bug, so I can't close it. I just tested with php 
5.4.6 and this problem seems to have been fixed. I'm guessing it was part of 
either bug #62629 or bug #62616
 [2012-08-30 22:51 UTC] tyrael@php.net
closing it on the request of burke.
 [2012-08-30 22:51 UTC] tyrael@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: tyrael
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 21:01:30 2024 UTC