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
и быть явным.