SplDoublyLinkedList::shift()
(PHP 5 >= 5.3.0, PHP 7)
Shifts a node from the beginning of the doubly linked list
说明
public SplDoublyLinkedList::shift(void) : mixed
参数
此函数没有参数。
返回值
The value of the shifted node.
错误/异常
ThrowsRuntimeExceptionwhen the data-structure is empty.
One may expect SplDoublyLinkedList::shift to properly maintain internal pointers, but this is not the case, this will yield no results, even if you rewind first <?php while ($splDoublyLinkedList->valid()) { yield $splDoublyLinkedList->shift(); } ?> It could be by design, but the following raises some more questions : <?php $test = new \SplDoublyLinkedList; $dataSet = [ ['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4], ]; foreach ($dataSet as $row) { $test->push($row); } echo "count: " . $test->count() . PHP_EOL; echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL; echo "current: " . var_export($test->current(), true) . PHP_EOL; echo "key: " . $test->key() . PHP_EOL; echo "1st shift: " . var_export($test->shift(), true) . PHP_EOL; echo "count: " . $test->count() . PHP_EOL; echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL; echo "current: " . var_export($test->current(), true) . PHP_EOL; echo "key: " . $test->key() . PHP_EOL; echo "2nd shift: " . var_export($test->shift(), true) . PHP_EOL; echo "count: " . $test->count() . PHP_EOL; echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL; echo "current: " . var_export($test->current(), true) . PHP_EOL; echo "key: " . $test->key() . PHP_EOL; echo "rewinding... " . PHP_EOL; $test->rewind(); echo "current: " . var_export($test->current(), true) . PHP_EOL; echo "2nd shift: " . var_export($test->shift(), true) . PHP_EOL; echo "count: " . $test->count() . PHP_EOL; echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL; echo "current: " . var_export($test->current(), true) . PHP_EOL; echo "key: " . $test->key() . PHP_EOL; ?> will result in : <?php /* count: 4 valid: false <== First thing to note, you have no valid pointer unless you rewind first current: NULL <== hence no current key: 0 <== but we have a valid key offsetGet(key): array ( <== indeed 'id' => 1, ) 1st shift: array ( <== and shift does return first row 'id' => 1, ) count: 3 <== and count is maintained as expected valid: false <== but internal pointer was left outside valid range current: NULL <== hence no current again key: 0 <== but we still have a valid key offsetGet(key): array ( <== indeed 'id' => 2, ) 2nd shift: array ( <== and shift does return first row 'id' => 2, ) count: 2 <== and count is maintained as expected valid: false <== still not valid etc .. current: NULL key: 0 offsetGet(key): array ( 'id' => 3, ) rewinding... <== now rewind current: array ( <== yay a current 'id' => 3, ) 3rd shift: array ( <== shift ok 'id' => 3, ) count: 1 <== count ok valid: true <== ouch valid current: NULL <== with no current key: 0 <== still our key is valid :o offsetGet(key): array ( 'id' => 4, ) */ ?> Conclusion : I may be missing something about why SplDoublyLinkedList::shift is not maintaining proper internal index in the first place, but I find it even more confusing to be able to end up with a valid valid() and a valid key() and no current() while there is obviously one. Tested on php 5.6.30 & 7.1.2 with the exact same result.