IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

foreach ne modifie pas les valeurs d'un tableau


Sujet :

Langage PHP

  1. #1
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut foreach ne modifie pas les valeurs d'un tableau
    Bonsoir,

    Je viens juste de me confronter à quelque chose d'incompréhensible concernant foreach.
    Selon le manuel PHP:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $arr = array(1, 2, 3, 4);
    foreach ($arr as $value) {
        $value = $value * 2;
    }
    // $arr vaut maintenant array(2, 4, 6, 8)
    unset($value); // Détruit la référence sur le dernier élément
    Et ben pas chez moi !
    Si je fais un var_dump($arr); le tableau est toujours égale à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    array
      0 => int 1
      1 => int 2
      2 => int 3
      3 => int 4
    Je n'arrive pas à comprendre ce comportement.
    Il n'y a que si je met $value en référence ($arr as &$value) que
    j'ai bien le résultat attendu sauf que à l'affichage du var_dump
    j'ai un & à la dernière valeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    array
      0 => int 2
      1 => int 4
      2 => int 6
      3 => &int 8
    Est ce que quelqu'un pourrait m'expliquer ce mystère ?

    Merci d'avance.

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    pour modifier c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach ($arr as &$value)

  3. #3
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    Oui c'est ce que j'ai fais.
    Mais que signifie le & sur le dernier élément du tableau ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    array
      0 => int 2
      1 => int 4
      2 => int 6
      3 => &int 8

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    en effet, c'est bizarre (perso, je ne connaissais pas cette syntaxe) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
    $arr = array(1, 2, 3, 4);
    foreach ($arr as &$value) {
        $value = $value * 2;
    }
    var_dump($arr);
    ?>
    Ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    array
      0 => int 2
      1 => int 4
      2 => int 6
      3 => &int 8
    &int 8 : mystère mystérieusement mystérieux...

    La méthode la plus "fiable" est encore :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
    $arr = array(1, 2, 3, 4);
    foreach ($arr as $i => $value) {
        $arr[$i] = $value * 2;
    }
    var_dump($arr);
    ?>
    Ca donne BIEN :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    array
      0 => int 2
      1 => int 4
      2 => int 6
      3 => int 8

  5. #5
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    en effet, c'est bizarre (perso, je ne connaissais pas cette syntaxe) :
    Si, tu as dû la rencontrer (le contraire m'étonnerait).

    C'est pour indiquer un "passage" par référence, et dans Php il y a quelques fonctions comme ça où un paramètre passe par référence.
    Comme sort(), asort(), array_walk(), etc ...

    Pour sort() par exemple :
    bool sort ( array &$array [, int $sort_flags = SORT_REGULAR ] )

    Ce qui est bizarre c'est vrai, c'est pourquoi le &int uniquement sur la dernière valeur du tableau ?
    A la limite, ça l'indiquerait sur toutes les valeurs ça me semblerait normal, car le &int indiquerait que le type est INTERGER et est une référence.


    Ceci dit, peut être que ça indique uniquement sur la dernière la valeur parce que cette dernière est une référence à la valeur précédente.
    Mais surtout que les valeurs précédentes (2 => int 6, etc ...) ne sont pas ou ne seraient plus des références.

    En somme, $value à la fin de la boucle vaut 8, mais pas 6, ni 4, ni 2, elles ont été "écrasées" à chaque tour de boucle.

    A mon humble avis.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message
    Si, tu as dû la rencontrer (le contraire m'étonnerait).
    J'avoue humblement que je manipule peu (et mal) les array. (je suis par contre très fort dans les "usines à gaz" !)
    Il m'a déjà fallu du temps pour assimiler (et donc utiliser efficacement) cette syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach ($arr as $i => $value) {
    J'apprends donc encore beaucoup sur le forum en lisant les réponses des autres !

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    625
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 625
    Points : 822
    Points
    822
    Par défaut
    Hello,

    La présence du & dans le var_dump ne fait que signaler qu'il existe une référence sur cette variable.

    Petite expérience :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    $a = range(0, 5);
    foreach($a as $val){
        $val *= 2;
    }
    unset($val); // on supprime la ref
    $b = &$a[3]; // on crée une ref sur un autre élément
     
    var_dump($a);
     
    array(6) {
      [0]=>
      int(0)
      [1]=>
      int(1)
      [2]=>
      int(2)
      [3]=>
      &int(3)
      [4]=>
      int(4)
      [5]=>
      int(5)
    }
    Sinon pour ce genre d'opération, tu peux aussi utiliser array_map, qui parait plus adapté. Un exemple avec une lambda (php > 5.3.jesaispascombien) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $a = range(0, 5);
    $a = array_map(function($x){return $x *= 2;}, $a);

  8. #8
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par Petibidon
    La présence du & dans le var_dump ne fait que signaler qu'il existe une référence sur cette variable.
    Ok
    La destruction (unset) de la variable avant le var_dump() démontre que cette référence s'applique bien sur la dernière valeur (ou donnée) du tableau.

    Ce qui peu encore le confirmer, c'est de modifier cette dernière valeur du tableau, et du coup $value prend la même valeur.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    $arr = array(1, 2, 3, 4, 5, 6);
    foreach ($arr as &$value) {
        $value = $value * 2;
    }
     
    $arr[5] = 50;
    echo '$arr[5] : '.$arr[5].'<br />';
    echo '$value : '.$value.'<br />';
     
    unset($value);
    var_dump($arr);
    ?>
    Affiche :
    $arr[5] : 50
    $value : 50 -> même valeur du fait que c'est une référence au dernier élément du tableau

  9. #9
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    Bonjour,
    en effet, c'est bizarre (perso, je ne connaissais pas cette syntaxe)

    Y'a ça aussi


  10. #10
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par stealth35 Voir le message
    Y'a ça aussi

    Synonyme de array_values()

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    Synonyme de array_values()
    oui et non, dans le sens ou un iterator sera un array (meme si un iterator_to_array rendra le meme chose), exemple avec ResourceBundle qui marche avec foreach qui n'est pas un Iterator, mais c'est tordu comme utilisation

  12. #12
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    Merci à tous pour toutes ces réponses et ces réflexions.
    En effet qui aurait pensé qu'un bête foreach contenait tant de mystères
    et de questionnements.
    Envoyé par Petibidon
    La présence du & dans le var_dump ne fait que signaler qu'il existe une référence sur cette variable.
    Répond parfaitement à ma question.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Je n'arrive pas a modifier les valeurs de mon tableau via mon UserForm
    Par Patouillou dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 24/02/2015, 16h15
  2. [AJAX] Ajax n'affiche pas les valeurs
    Par fbe66 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 05/11/2007, 10h05
  3. Réponses: 2
    Dernier message: 01/06/2007, 11h40
  4. [Zend_Db_Profiler] ne retourne pas les valeurs
    Par misterniark dans le forum Zend_Db
    Réponses: 2
    Dernier message: 20/04/2007, 22h54
  5. Réponses: 1
    Dernier message: 24/10/2006, 15h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo