PHP - изменение текущего объекта в цикле foreach

Мне было интересно, можно ли отредактировать текущий объект, который обрабатывается в цикле foreach

Я работаю с массивом объектов $questions, и я хочу пройти и искать ответы, связанные с этим объектом вопроса в моем db. Поэтому для каждого вопроса отправляйте объекты ответа и обновляйте текущий цикл $question внутри my foreach, чтобы я мог выводить/обрабатывать в другом месте.

foreach($questions as $question){
    $question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}

Ответ 1

Есть 2 способа сделать это

foreach($questions as $key => $question){
    $questions[$key]['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}

Таким образом, вы сохраняете ключ и можете снова его обновить в основной переменной $questions

или же

foreach($questions as &$question){

Добавление & будет держать $questions обновленными. Но я бы сказал, что первое рекомендуется, хотя это короче (см. Комментарий Пейстей)

Согласно документации foreach по PHP:

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

Ответ 2

Конечно, используя array_map, и если использование контейнера, реализующего ArrayAccess для вывода объектов, - это более разумный, семантический способ сделать это?

Семантика карты массива похожа на большинство языков и реализаций, которые я видел. Он предназначен для возврата модифицированного массива на основе элемента входного массива (высокий уровень игнорирования предпочтений языка компиляции/времени выполнения); цикл предназначен для выполнения большей логики.

Для получения объектов с помощью ID/PK, в зависимости от того, используете ли вы SQL или нет (кажется, предлагается), я бы использовал фильтр, чтобы получить массив действительных PK, затем вставить в запятую и поместить в SQL IN(), чтобы вернуть результат. Он делает один вызов вместо нескольких через SQL, оптимизируя бит цикла call->wait. Самое главное, мой код хорошо читал бы кого-то с любого языка с определенной степенью компетентности, и мы не сталкивались с проблемами мутируемости.

<?php

$arr = [0,1,2,3,4];
$arr2 = array_map(function($value) { return is_int($value) ? $value*2 : $value; }, $arr);
var_dump($arr);
var_dump($arr2);

против

<?php

$arr = [0,1,2,3,4];
foreach($arr as $i => $item) {
    $arr[$i] = is_int($item) ? $item * 2 : $item;
}
var_dump($arr);

Если вы знаете, что вы делаете, никогда не будет иметь проблем с изменением (имея в виду, если вы намереваетесь перезаписать $arr, вы всегда можете $arr = array_map и быть явным.