Почему я не могу обновлять данные в массиве с помощью цикла foreach?

Я пытаюсь запустить очистку работы с данными в массиве, в частности, преобразовать время эпохи в YYYY-MM-DD.

Я пробовал эту функцию изначально:

foreach ($data as $row) {
    $row['eventdate'] = date('Y-m-d', $row['eventdate']);
}

echo '<pre>';
print_r($data);
echo '</pre>';

Однако цикл foreach не обновлял данные при его выводе.

Следующий цикл for работал:

for ($i=0; $i<count($data); $i++) {
    $data[$i]['eventdate'] = date('Y-m-d', $data[$i]['eventdate']);
}

Почему первый цикл вышел из строя, а вторая работала? Разве они не те же?

Ответ 1

Когда вы используете цикл foreach в том виде, в котором вы сейчас находитесь, foreach ($data as $row) {, $row используется "по значению", а не "по ссылке".

Попробуйте обновить ссылку, добавив & в $row:

foreach ($data as &$row) {
    $row['eventdate'] = date('Y-m-d', $row['eventdate']);

Или вы можете использовать метод key/value:

foreach ($data as $index => $row) {
    $data[$index]['eventdate'] = date('Y-m-d', $row['eventdate']);

Ответ 2

Исходный пример только передает строку по значению, а не по ссылке.

Из документов

Чтобы иметь возможность напрямую изменять элементы массива в цикле предшествует $value с помощью &. В этом случае значение будет присвоено Ссылка

Следовательно, либо пройдем по ссылке

foreach ($data as &$row) {
   $row['eventdate'] = date('Y-m-d', $row['eventdate']);
}

или используйте более явный синтаксис

foreach ($data as $key => $value) {
    $data[$key]['eventdate'] = date('Y-m-d', $value['eventdate']);
}

Также важно это предупреждение в документах

Ссылка на значение $и последний элемент массива остаются даже после foreach loop. Рекомендуется уничтожить его unset()