Ich erstelle eine Klasse, die Iterator
und ArrayAccess
implementiert. Die Iterator-Tests sind fehlgeschlagen. Wenn ich eine print_r()
on current($object)
mache, bekomme ich das zugrunde liegende Array, nicht das erste Objekt.PHP-Iterator-Schnittstelle: current() gibt das zugrunde liegende Array anstelle des ersten Werts zurück
Der folgende Code ist ein Beispiel aus meiner tatsächlichen Klasse, die das Problem veranschaulicht. Dies ist das erste Mal, dass ich Iterator
in einer meiner Klassen implementiert habe, also mache ich das wahrscheinlich irgendwo falsch. Was muss ich ändern, damit der Iterator ordnungsgemäß funktioniert?
Code:
class Collection implements \ArrayAccess, \Iterator
{
private $_array = array();
public function __invoke() { return $this->_array; }
public function offsetExists($offset) { return array_key_exists($offset, $this->_array); }
public function offsetGet($offset) { return $this->_array[$offset]; }
public function offsetSet($offset, $value) { $this->_array[$offset] = $value; }
public function offsetUnset($offset) { unset($this->_array[$offset]); }
public function current() { return current($this->_array); }
public function key() { return key($this->_array); }
public function next() { return next($this->_array); }
public function rewind() { return reset($this->_array); }
public function valid() { return is_null(key($this->_array)); }
}
class TemporaryTest extends \PHPUnit\Framework\TestCase
{
private $_test_object;
public function setUp()
{
$this->_test_object = new Collection();
$this->_test_object['alpha'] = 'blah';
$this->_test_object['beta'] = 'yada';
$this->_test_object['gamma'] = 'woot';
}
public function testIteratorOnInternalArray()
{
$o = $this->_test_object;
$a = $o();
$this->assertEquals('blah', current($a));
$this->assertEquals('yada', next($a));
$this->assertEquals('woot', next($a));
}
public function testIterator()
{
print_r(current($this->_test_object));
$this->assertEquals('blah', current($this->_test_object));
$this->assertEquals('yada', next($this->_test_object));
$this->assertEquals('woot', next($this->_test_object));
$this->assertFalse($this->_test_object->valid());
reset($this->_test_object);
$this->assertEquals('blah', current($this->_test_object));
}
public function testForEach()
{
$actual = array();
foreach ($this->_test_object as $key => $value) { $actual[$key] = $value; }
$this->assertEquals(array('alpha' => 'blah', 'beta' => 'yada','gamma' => 'woot'), $actual);
}
}
Unit-Test-Ausgang:
.FArray
(
[alpha] => blah
[beta] => yada
[gamma] => woot
)
F 3/3 (100%)
There were 2 failures:
1) TemporaryTest::testIterator
Array (...) does not match expected type "string".
/Users/mac/Projects/NetShapers/Gears/core/Tests/Unit/TemporaryTest.php:83
2) TemporaryTest::testForEach
Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
Array (
- 'alpha' => 'blah'
- 'beta' => 'yada'
- 'gamma' => 'woot'
)
/Users/mac/Projects/NetShapers/Gears/core/Tests/Unit/TemporaryTest.php:97
Ja, das ist genau das, was ich erwarte. Hast du den Teil gesehen, wo auch der 'foreach' Test fehlschlägt? –
@JayBienvenu Ich habe die Antwort mit dem Grund aktualisiert, warum Ihre 'foreach' fehlschlägt –
Also die Antwort ist, dass ich einen Tippfehler in' valid() 'hatte, und' current() 'funktioniert nicht mit Iterator wie' count() 'und andere Funktionen tun? –