web-dev-qa-db-fra.com

PHP - Modifie l'objet en cours dans une boucle foreach

Je me demandais s'il était possible de modifier l'objet actuel traité dans une boucle foreach

Je travaille avec un tableau d'objets $questions Et je veux parcourir et chercher les réponses associées à cet objet question dans ma base de données. Donc, pour chaque question, allez chercher les objets de réponse et mettez à jour la boucle actuelle $questionà l'intérieur mon foreach afin que je puisse sortir/traiter ailleurs.

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

Il y a 2 façons de faire cela

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

De cette façon, vous enregistrez la clé afin que vous puissiez la mettre à jour à nouveau dans le menu principal $questions variable

ou

foreach($questions as &$question){

Ajout du & gardera le $questions mis à jour. Mais je dirais que le premier est recommandé même s'il est plus court (voir le commentaire de Paystey)

Par la PHP foreach documentation :

Afin de pouvoir modifier directement les éléments du tableau dans la boucle, faites précéder $ value par &. Dans ce cas, la valeur sera attribuée par référence.

186
Rene Pot

Utiliser sûrement array_map Et si vous utilisez un conteneur implémentant ArrayAccess pour dériver des objets est simplement une manière sémantique plus intelligente d’agir à ce sujet?

La sémantique des cartes de matrice est similaire dans la plupart des langues et des implémentations que j'ai vues. Il est conçu pour renvoyer un tableau modifié basé sur un élément de tableau en entrée (préférence du type compilation/exécution du haut niveau ignorée); une boucle est destinée à effectuer plus de logique.

Pour récupérer des objets par ID/PK, selon que vous utilisiez SQL ou non (il semble suggéré), j'utiliserais un filtre pour m'assurer d'obtenir un tableau de PK valides, puis imploser avec une virgule et placer dans un SQL IN() clause pour renvoyer le résultat. Il effectue un appel au lieu de plusieurs via SQL, optimisant un peu le cycle call->wait. Plus important encore, mon code lirait bien à quelqu'un de n'importe quelle langue possédant un certain degré de compétence et nous ne rencontrions pas de problèmes de mutabilité.

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

contre

<?php

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

Si vous savez que ce que vous faites n'aura jamais de problèmes de mutabilité (en gardant à l'esprit si vous avez l'intention d'écraser $arr, Vous pourrez toujours $arr = array_map Et être explicite.

5
MrMesees