1--TEST-- 2SPL: iterator_to_array() and exceptions from delayed destruct 3--FILE-- 4<?php 5 6class MyArrayIterator extends ArrayIterator 7{ 8 static protected $fail = 0; 9 public $state; 10 11 static function fail($state, $method) 12 { 13 if (self::$fail == $state) 14 { 15 throw new Exception("State $state: $method()"); 16 } 17 } 18 19 function __construct() 20 { 21 $this->state = MyArrayIterator::$fail; 22 self::fail(0, __FUNCTION__); 23 parent::__construct(array(1, 2)); 24 self::fail(1, __FUNCTION__); 25 } 26 27 function rewind(): void 28 { 29 self::fail(2, __FUNCTION__); 30 parent::rewind(); 31 } 32 33 function valid(): bool 34 { 35 self::fail(3, __FUNCTION__); 36 return parent::valid(); 37 } 38 39 function current(): mixed 40 { 41 self::fail(4, __FUNCTION__); 42 return parent::current(); 43 } 44 45 function key(): string|int|null 46 { 47 self::fail(5, __FUNCTION__); 48 return parent::key(); 49 } 50 51 function next(): void 52 { 53 self::fail(6, __FUNCTION__); 54 parent::next(); 55 } 56 57 function __destruct() 58 { 59 self::fail(7, __FUNCTION__); 60 } 61 62 static function test($func, $skip = null) 63 { 64 echo "===$func===\n"; 65 self::$fail = 0; 66 while(self::$fail < 10) 67 { 68 try 69 { 70 var_dump($func(new MyArrayIterator())); 71 break; 72 } 73 catch (Exception $e) 74 { 75 echo $e->getMessage() . "\n"; 76 } 77 if (isset($skip[self::$fail])) 78 { 79 self::$fail = $skip[self::$fail]; 80 } 81 else 82 { 83 self::$fail++; 84 } 85 try { 86 $e = null; 87 } catch (Exception $e) { 88 } 89 } 90 } 91} 92 93MyArrayIterator::test('iterator_to_array'); 94MyArrayIterator::test('iterator_count', array(3 => 6)); 95 96?> 97--EXPECT-- 98===iterator_to_array=== 99State 0: __construct() 100State 1: __construct() 101State 2: rewind() 102State 3: valid() 103State 4: current() 104State 5: key() 105State 6: next() 106State 7: __destruct() 107array(2) { 108 [0]=> 109 int(1) 110 [1]=> 111 int(2) 112} 113===iterator_count=== 114State 0: __construct() 115State 1: __construct() 116State 2: rewind() 117State 3: valid() 118State 6: next() 119State 7: __destruct() 120int(2) 121