Bug #62810 [NEW]: IteratorIterator changes the class of the inner iterator, breaking some calls
From: burke dot cates at gmail dot com
Operating system: Linux
PHP version: 5.4.5
Package: SPL related
Bug Type: Bug
Bug description:IteratorIterator changes the class of the inner iterator, breaking some calls
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:
--
Edit bug report at https://bugs.php.net/bug.php?id=62810&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=62810&r=trysnapshot54
Try a snapshot (PHP 5.3): https://bugs.php.net/fix.php?id=62810&r=trysnapshot53
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=62810&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=62810&r=fixed
Fixed in SVN and need be documented: https://bugs.php.net/fix.php?id=62810&r=needdocs
Fixed in release: https://bugs.php.net/fix.php?id=62810&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=62810&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=62810&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=62810&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=62810&r=support
Expected behavior: https://bugs.php.net/fix.php?id=62810&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=62810&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=62810&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=62810&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=62810&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=62810&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=62810&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=62810&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=62810&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=62810&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=62810&r=mysqlcfg
Thread (3 messages)
- burke dot cates at gmail dot com