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

Reply via email to