PHP оператор foreach переходит в конец, когда массив объединяется в начале

Я столкнулся с довольно неожиданным поведением при выполнении кода ниже.

Вот что происходит:

Раз условие (if ($item_key === 3 || $item_key === 7)) и пункт 3 перемещается в начало элемента $ items_arr, foreach оператор переходит к последнему индексу. В результате чего дальнейшие индексы, включая пункт 7, не обрабатываются.

Я хотел бы знать, что происходит внутри страны, и почему в foreach оператор один раз массив сплайсинга в начале.

Интересно, где такого поведения нет, когда некоторые массивы сращиваются в конце $ items_arr.

Любая мысль ценится. Заранее спасибо.

<?php

$items_arr = [];

// adding some items
for ($i = 0; $i < 10; $i++)
{
    $items_arr[] = [
        "id" => $i,
        "name" => "Item {$i}",
    ];
}

/*
 * Some items need to be moved at the
 * beginning of the array.
 */
$i = 0;
foreach ($items_arr as $item_key => &$item)
{
    print "Processing: {$item['name']}" . PHP_EOL;

    // some condition is met
    if ($item_key === 3 || $item_key === 7)
    {
        array_splice($items_arr, $i, 0, [$item]);
        $i++;
        unset($items_arr[$item_key + $i]);
    }
}

Выход:

Processing: Item 0
Processing: Item 1
Processing: Item 2
Processing: Item 3
Processing: Item 9

1 ответ

Вы модифицируете $items_arr внутри цикла, который десинхронизирует цикл foreach (честно говоря, это лучший способ, которым я могу это описать). Вам нужно будет замкнуть петлю и начать заново всякий раз, когда произошла мутация.

$mutated = null;
do {
    $mutated = false;
    foreach ($items_arr as $item_key => &$item)
    {
        print "Processing: {$item['name']}" . PHP_EOL;

        // some condition is met
        if ($item_key === 3 || $item_key === 7)
        {
            array_splice($items_arr, $i, 0, [$item]);
            $i++;
            unset($items_arr[$item_key + $i]);
            $mutated = true;
            break;
        }
    }
}
while($mutated == true);
Другие вопросы по тегам