PHP - Ändert das aktuelle Objekt in jeder Schleife

109

Ich habe mich gefragt, ob es möglich ist, das aktuelle Objekt zu bearbeiten, das in einer foreachSchleife verarbeitet wird

Ich arbeite mit einer Reihe von Objekten $questionsund möchte in meiner Datenbank nach den Antworten suchen, die mit diesem Frageobjekt verknüpft sind. Holen Sie sich also für jede Frage die Antwortobjekte und aktualisieren Sie den Strom $question in meiner foreachSchleife, damit ich ihn an anderer Stelle ausgeben / verarbeiten kann.

foreach($questions as $question){
    $question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
Garbit
quelle
Wie sowohl ArtjomKurapov als auch @topener vorschlugen, suchte ich mit dem & -Zeichen nach "Referenzübergabe". Danke Jungs :)
Ich

Antworten:

206

Es gibt zwei Möglichkeiten, dies zu tun

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

Auf diese Weise können Sie den Schlüssel speichern, so dass Sie es wieder in der Haupt aktualisieren können $questionsvariable

oder

foreach($questions as &$question){

Durch Hinzufügen von &wird das $questionsUpdate aktualisiert. Aber ich würde sagen, der erste wird empfohlen, obwohl dieser kürzer ist (siehe Kommentar von Paystey)

Gemäß der PHP- foreachDokumentation :

Um Array-Elemente innerhalb der Schleife direkt ändern zu können, muss $ value mit & vorangestellt werden. In diesem Fall wird der Wert als Referenz zugewiesen.

Rene Pot
quelle
32
Verweise auf foreachwird wirklich nicht empfohlen, da die Art und Weise, wie der foreachWertteil der Schleife umgangen wird, zu einem unvorhersehbaren Verhalten führt. Es kann länger dauern, aber Sie sind hier mit Methode 1 weitaus sicherer.
Paystey
1
Ich habe gerade eine verblüffte Stunde damit verbracht, ein Problem zu debuggen, das durch die Verwendung einer Referenz in einem Foreach verursacht wurde. Ich habe denselben Variablennamen für einen zweiten foreach-Aufruf wiederverwendet - da ich den ersten als Referenz übergeben hatte, wurde das letzte Element im Array ständig geändert! Die Verwendung eines expliziten Index hätte dieses Problem nicht gehabt.
Hippyjim
7
@Paystey können Sie Ihre Quellen zitieren oder eine detaillierte Erklärung geben?
Nico
2
Warum sollte das Manipulieren von Referenzen unsicher sein? Ist C / C ++, wo Sie Referenzen überall manipulieren müssen, unsicher? Es liegt an Ihnen, es sicher zu machen oder nicht, nicht die Sprache.
Kalzem
2
@BabyAzerty: Paystey hat keine Referenzen "im Allgemeinen" gesagt, aber in foreachBezug auf Horror wie diesen: stackoverflow.com/questions/3307409/… (@Nico, FYI auch.)
Gr.
6

Sicherlich ist die array_mapVerwendung eines Containers, der ArrayAccesszum Ableiten von Objekten implementiert wird, nur eine intelligentere, semantische Methode, um dies zu erreichen.

Die Array-Map-Semantik ist in den meisten Sprachen und Implementierungen, die ich gesehen habe, ähnlich. Es wurde entwickelt, um ein modifiziertes Array basierend auf dem Eingabe-Array-Element zurückzugeben (hohe Ebene ohne Berücksichtigung der Sprachkompilierungs- / Laufzeittyp-Einstellungen). Eine Schleife soll mehr Logik ausführen.

Zum Abrufen von Objekten nach ID / PK würde ich, je nachdem, ob Sie SQL verwenden oder nicht (es wird empfohlen), einen Filter verwenden, um sicherzustellen, dass ich ein Array gültiger PKs erhalte, dann mit Komma implodieren und in eine SQL- IN()Klausel einfügen Geben Sie die Ergebnismenge zurück. Es wird ein Aufruf anstelle mehrerer über SQL ausgeführt, wodurch ein Teil des call->waitZyklus optimiert wird. Am wichtigsten ist, dass mein Code für jemanden aus jeder Sprache mit einem gewissen Grad an Kompetenz gut lesbar ist und wir nicht auf Veränderlichkeitsprobleme stoßen.

<?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);

vs.

<?php

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

Wenn Sie wissen, was Sie tun, werden Sie niemals Probleme mit der Veränderlichkeit haben (wenn Sie beabsichtigen, diese zu überschreiben, können $arrSie dies immer $arr = array_mapund explizit tun .

MrMesees
quelle
2
Viel intuitiver als ein Foreach - genau dafür ist diese Funktion konzipiert.
Benjamin