web-dev-qa-db-ja.com

PHP-foreachループで現在のオブジェクトを変更します

foreachループ内で処理されている現在のオブジェクトを編集できるかどうか疑問に思っていました

私はオブジェクトの配列$questionsを操作しており、データベース内でその質問オブジェクトに関連付けられた回答を探したいと思います。したがって、質問ごとに回答オブジェクトを取得し、現在の$questioninside my foreachループを更新して、他の場所で出力/処理できるようにします。

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

これを行うには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が常に更新されます。しかし、これは短くても、最初のものをお勧めします(Paysteyのコメントを参照)

PHP foreachドキュメント

ループ内の配列要素を直接変更できるようにするには、$ valueの前に&を付けます。その場合、値は参照によって割り当てられます。

186
Rene Pot

確かにarray_mapを使用し、ArrayAccessを実装するコンテナを使用してオブジェクトを派生させることは、これを実行するためのよりスマートで意味的な方法ですか?

配列マップのセマンティクスは、私が見たほとんどの言語と実装で類似しています。入力配列要素に基づいて変更された配列を返すように設計されています(言語のコンパイル/実行時の型設定を無視する高レベル)。ループは、より多くのロジックを実行するためのものです。

ID/PKでオブジェクトを取得するには、SQLを使用しているかどうかに応じて(推奨されるようです)、フィルターを使用して有効なPKの配列を取得し、コンマで内包してSQL IN()句は結果セットを返します。 SQLを介した複数の呼び出しの代わりに1つの呼び出しを行い、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にして明示的にすることができます。

5
MrMesees