SplDoublyLinkedList::shift

(PHP 5 >= 5.3.0, PHP 7)

SplDoublyLinkedList::shiftShifts a node from the beginning of the doubly linked list

说明

public mixed SplDoublyLinkedList::shift ( void )

参数

此函数没有参数。

返回值

The value of the shifted node.

错误/异常

Throws RuntimeException when the data-structure is empty.

User Contributed Notes

fabs2s at marsatak dot org 28-Feb-2017 07:41
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.