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


111

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

私はオブジェクトの配列を使用していて、$questions自分のデータベースでその質問オブジェクトに関連付けられている回答を調べて調べたいと思います。したがって、各質問に対して回答オブジェクトをフェッチし、ループ$question の現在のオブジェクトを更新して、foreach他の場所で出力/処理できるようにします。

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

ArtjomKurapovと@topenerの両方が示唆したように、&記号を使用して「参照渡し」を探していました。おかげで:)良い一日を
ガービット

回答:


207

これを行うには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更新されたままになります。しかし、これは短いですが、最初のものが推奨されると思います(Payseyのコメントを参照)

パーPHPのforeachドキュメント

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


32
での参照foreachは実際にお勧めforeachできません。ループの値の部分をパスする方法では、予測できない動作が発生します。それはより長いかもしれませんが、ここで方法1を使用する方がはるかに安全です。
Paystey

1
foreachで参照を使用することによって引き起こされる問題をデバッグするのに困惑した時間を費やしました。2番目のforeach呼び出しに同じ変数名を再利用しました。最初の参照を参照渡ししたので、配列の最後の項目を変更し続けました!明示的なインデックスを使用しても、この問題はありませんでした。
Hippyjim 2014年

7
@Paysteyは、出典を引用したり、詳細な説明をしたりできますか?
ニコ

2
参照の操作が安全でないのはなぜですか?どこでも参照を操作する必要があるC / C ++は安全ではありませんか?言語ではなく、安全にするかどうかはあなた次第です。
カルゼム2016

2
@BabyAzerty:Paysteyは参照を「一般的に」言っていませんでしたがforeach、次のような恐怖に関しては:stackoverflow.com/questions/3307409/…(@Nico、FYI、too。)
Sz。

6

確かに使用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でも明示的にすることができます)。


2
foreachを実行するよりもはるかに直感的です-これはまさにこの関数の目的です。
ベンジャミン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.