web-dev-qa-db-fra.com

PHP foreach change les valeurs du tableau d'origine

Je suis très nouveau dans les tableaux multi-dimensionnels, ce qui me dérange énormément.

Mon tableau est comme suit:

$fields = array(
    "names" => array(
         "type"         => "text",
         "class"        => "name",
         "name"         => "name",
         "text_before"  => "name",
         "value"        => "",
         "required"     => true,
    )
)

Ensuite, j'ai obtenu une fonction vérifiant si ces entrées sont renseignées, si elles sont requises.

function checkForm($fields){
    foreach($fields as $field){
        if($field['required'] && strlen($_POST[$field['name']]) <= 0){
            $fields[$field]['value'] = "Some error";
        }
    }
    return $fields;
}

Maintenant, mon problème est cette ligne

$fields[$field]['value'] = "Some error";

Je veux changer le contenu du tableau d'origine, puisque je renvoie ceci, mais comment puis-je obtenir le nom du tableau actuel (noms dans cet exemple) dans ma boucle foreach?

121
Jeppe

En PHP, passer par référence (&) est controversé. Je vous recommande de ne pas l'utiliser sauf si vous savez pourquoi vous en avez besoin et testez les résultats.

Je recommanderais de faire ce qui suit:

foreach ($fields as $key => $field) {
    if ($field['required'] && strlen($_POST[$field['name']]) <= 0) {
        $fields[$key]['value'] = "Some error";
    }
}

Donc, utilisez essentiellement $field lorsque vous avez besoin des valeurs, et $fields[$key] lorsque vous devez modifier les données.

224
Vlad Preda

Utilisez &:

foreach($arr as &$value)
{
     $value = $newVal;
}

& passe une valeur du tableau comme référence et ne crée pas une nouvelle instance de la variable. Ainsi, si vous changez la référence, la valeur d'origine changera.

http://php.net/manual/en/language.references.pass.php

Éditer 2018
Cette réponse semble être favorisée par de nombreuses personnes sur Internet, raison pour laquelle j'ai décidé d'ajouter plus d'informations et des mots de prudence.
Bien que passer par référence dans foreach (ou fonctions) soit une solution propre et brève, pour de nombreux débutants, cela pourrait être un piège dangereux.

  1. Les boucles dans PHP n'ont pas leur propre portée. - @Mark Amery

    Cela pourrait être un problème grave lorsque les variables sont réutilisées dans le même périmètre. ne autre SO question illustre bien pourquoi cela pourrait poser problème.

  2. Comme foreach repose sur le pointeur de tableau interne situé dans PHP 5, sa modification dans la boucle peut entraîner un comportement inattendu. - PHP docs pour foreach

    Désactiver un enregistrement ou modifier la valeur de hachage (la clé) lors de l'itération sur la même boucle peut entraîner des comportements potentiellement inattendus dans PHP <7. Le problème devient encore plus compliqué lorsque le tableau lui-même est une référence.

  3. Pour chaque performance.
    En général, PHP préfère passer par valeur en raison de la fonctionnalité de copie sur écriture. Cela signifie qu'en interne, PHP ne créera pas de données en double, à moins que la copie en soit modifiée. On peut se demander si passer par référence dans foreach offrirait une amélioration des performances. Comme c'est toujours le cas, vous devez tester votre scénario spécifique et déterminer quelle option utilise le moins de mémoire et moins de temps processeur. Pour plus d'informations, voir l'article SO lié ci-dessous par NikiC.

  4. Lisibilité du code.
    La création de références dans PHP est une chose qui devient rapidement incontrôlable. Si vous êtes un novice et que vous n’avez pas le plein contrôle de ce que vous faites, il est préférable de ne pas vous référer à des références. Pour plus d'informations sur l'opérateur &, consultez ce guide: Référence - Que signifie ce symbole en PHP?
    Pour ceux qui veulent en savoir plus sur cette partie de PHP langage: explications sur les références PHP

Une très belle explication technique de @NikiC de la logique interne de PHP pour chaque boucle:
Comment fonctionne PHP 'foreach'?

132
Dharman

Utilisez foreach($fields as &$field){ - vous travaillerez donc avec le tableau d'origine.

Ici est plus sur le passage par référence.

12
k102
function checkForm(& $fields){
    foreach($fields as $field){
        if($field['required'] && strlen($_POST[$field['name']]) <= 0){
            $fields[$field]['value'] = "Some error";
        }
    }
    return $fields;
}

Voici ce que je suggère de passer par référence

0
Sagar Kadam