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 :

Modifier array dans array avec noms dynamiques


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2012
    Messages : 27
    Points : 18
    Points
    18
    Par défaut Modifier array dans array avec noms dynamiques
    Bonjour,

    Soit un tableau comme suit:
    Nom : Capture d’écran 2015-12-08 à 15.33.29.png
Affichages : 103
Taille : 13,8 Ko

    Je souhaite créer un array($classe) qui contiendra lui même des array($nom_eleve), un pour chaque élève.
    L'array($nom_eleve) aura ainsi pour chaque devoir une clef('num_devoir') et pour valeur la note correspondante ('note').

    Pour Marie, le résultat serait donc:
    $Marie = array(
    #D1 => 8
    #D2 => 5
    #D4 => 10;
    )

    Ceci afin de pouvoir réaliser un tableau avec toutes les notes par élève.
    J'ai un code qui fonctionne à moitié, mais qui bloque au moment où l'array est déjà trouvé et qu'il faut y insérer une nouvelle clef+valeur.
    Le problème notamment et que les arrays et leurs clefs ont des noms dynamiques et je ne m'y retrouve pas lorsqu'il faut ajouter une clef à tel array.
    Mon code:

    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
    <?php
                        $bdd = new PDO('mysql:host=localhost;dbname=test19_11', 'root', 'root', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
                        $requete = $bdd->prepare('SELECT * FROM `voti` ORDER BY `Nom_Eleve` ASC');
     
                         $requete->execute();                        
                         $classe = array();
     
                          while ($data = $requete->fetch())
                                  {
                                    if (!isset($classe[$data['Nom_Eleve']]))
                                          {
                                            //l'array de l'élève n'existe pas, il est donc créé. Cette partie marche.
                                            $classe[$data['Nom_Eleve']] = array(
                                              'D'.$data['Num_Devoir'] => $data['Note'] );
                                          }
                                  else
                                  {
                                    //L'array existe déjà, 'D'.$data['Num_Devoir']=> $data['Note'] est ajoutée à l'array.
                                    $classe[$data['Nom_Eleve']['D'.$data['Num_Devoir']]] =  $data['Note'] );
                                  }
     
                                  } 
                                   '<p>'.var_dump($classe).'</p>';?>
    Comment puis-je faire pour ajouter $classe[$data['Marie'][D4]] => $data['Note'] par exemple ?
    Je me suis perdu. Peut-être faut-il renommer les arrays de suite du genre $eleve = $classe[$data['Nom_Eleve']] pour pouvoir ensuite l'appeler facilement?

    D'avance merci beaucoup pour votre temps

  2. #2
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 275
    Points
    3 275
    Par défaut
    Il y a une erreur dans tes crochets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $classe[$data['Nom_Eleve']]['D'.$data['Num_Devoir']] =  $data['Note'];

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2012
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    Merci beaucoup ça marche!
    Cependant, lorsque je fais un var_dump($classe) alors tous les arrays s'affichent.
    Mais si je fais un var_dump($nom_eleve) il me renvoie NULL, et ce, que je place le var_dump dans les conditions{} ou tout à la fin du script.

    Si c'est un array pourquoi je ne peux pas l'afficher sans passer par $classe[$nom_eleve] ?
    Autre question toute bête, comment puis-je renommer l'array à peine créé?
    De sorte que $classe[$data['Nom_Eleve']]['D'.$data['Num_Devoir']] devienne $num_devoir ?

  4. #4
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 275
    Points
    3 275
    Par défaut
    Créé une variable permanente pour chaque élément en dehors du tableau ne serait pas judicieux. En effet, si tu modifies ton tableau par la suite, ta variable ne possèderait plus les bonnes valeures. Et inversement.

    var_dump($nom_eleve) ne donne rien étant donné que $nom_eleve n'est pas défini.

    Par contre quand tu parcours ton tableau avec foreach, tu peux donné un nom à l'élément courant de ton tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach($classe as $eleve) {
    //$eleve vaut quelque chose...
    }

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2012
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    Merci pour la réponse désolé je testais encore le code je n'avais pas encore répondu.
    Ca marche mais j'ai un autre problème et même en cherchant un peu partout je n'avance pas.

    Maintenant ce que je veux, c'est qu'à la fin du code une fois les arrays construis, un controle soit effectué pour vérifier les 'devoirs' auquels n'ont pas participé les élèves, et donc leur assigner malgré tout une clé pour le devoir, avec la valeur "". Je sais ça semble bizarre mais pour ensuite construire le tableau il me faut les éléments, même s'ils sont vides.

    Bref du coup j'ai un code mais je ne comprends pas ce qui ne marche pas.

    Voici le morceau de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    while ($requete2= $requete->fetch())
    {
      $eleve= &$classe[$requete2['Nome_Eleve']] ;
     
                    for ($clefdevoir = 1; $clefdevoir <= $devoirmax; $clefdevoir++)
                    {   
                        if (!isset($eleve[$clefdevoir])) 
                        {
                         $eleve[$clejournee] = "";
                        }
                    }
    }
    Je précise que $devoirmax est une variable qui retient quel est le numéro de devoir le plus élevé (cette variable fonctionne normalement).

    Le problème c'est que le code ne me remplit pas les arrays des élèves comme prévu. Lorsqu'il n'ont pas participé au devoir, ils leur manque ce devoir dans leur array alors qu'il devrait être créé comme clef et vide de valeur.

    Mais si je recherche une valeur absolue ça fonctionne.
    ex: Si au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $classe[$requete2['Nome_Eleve']][$clefdevoir ] = ""
    je mets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $classe['MARIE'][$clefdevoir] = ""
    )
    alors cela me crée bien la clef manquante.

    Une idée ? J'ai testé plusieurs solutions pour récupérer le nom de l'élève (qui est aussi un array donc je pense que le problème vient de là) mais avec des variables ça ne marche pas!

    Merci pour votre aide!

  6. #6
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 628
    Points
    3 628
    Billets dans le blog
    8
    Par défaut
    D'une façon générale, si tu veux modifier un tableau PHP déjà existant, et pas seulement le lire, il faut procéder ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //par exemple tu veux ajouter une nouvelle clé et l'alimenter selon une condition
    $i=0;
    do{
       if($i%2==0){
          $data[$i]['new_key']='toto'.$i;
       }
       else{
          $data[$i]['new_key']='';
       }
       $i++;
    }while($i<sizeof($data));
    A toi d'adapter maintenant, mais tout ce qui est du type foreach($data as $row) ne fonctionnera pas pour modifier ton tableau... En effet, c'est comme si tu travaillais sur une projection, pas sur le tableau lui-même.

  7. #7
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 275
    Points
    3 275
    Par défaut
    Je pense que tu t'y prends mal avec ton tableau classe. Je pense que ton algo peut-être amélioré.

    Par étape ça pourrait donner :

    - Tu récupères la liste des notes
    - Tu récupères la liste des devoirs
    - Tu récupère la liste des élèves
    - Pour chaque élève (et tu ne remplis ta variable classe qu'à ce moment là) :
    - Tu créé l'élément dans le tableau classe
    - Pour chaque devoir :
    - S'il existe une note pour l'élève pour ce devoir, tu la rajoutes, sinon tu mets ""

    Et voilà, simple et efficace.

    PS : évite les références aussi juste quand il s'agit de "simplification d'écriure", elle ne sont pas prévues pour ça et risque plus de t'embrouiller qu'autre chose au final

  8. #8
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2012
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    @Dendrite: merci pour ta réponse mais Do_While éxécute la commande à la première itération pour ensuite vérifier lors de la seconde si elle se vérifié toujours. Alors que je ne sais pas à l'avance si la commande doit s'éxécuter pour la première itération.

    @Spartacusply: oui c'est vrai que ça peut-être plus simple de recommencer comme ça.
    Mais question de détail j'aurais juste voulu comprendre pourquoi ma solution ne marche pas car le fait d'appeler à comparer des éléments d'array ou des arrays eux mêmes me sera forcément utile par la suite. Pour les référencements je ne savais pas, je pensais qu'il s'agissait juste de changer de nom d'un parcours long et complexe pour l'utiliser plus simplement.

    Je vais retenter ma chance en changeant la procédure comme tu me l'as indiqué.
    Si quelqu'un sait pourquoi ce code-ci ne modifie pas l'array comme prévu je le remercie bien.

    Merci pour votre aide

  9. #9
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Citation Envoyé par LeSmoox Voir le message
    @Dendrite: merci pour ta réponse mais Do_While éxécute la commande à la première itération pour ensuite vérifier lors de la seconde si elle se vérifié toujours. Alors que je ne sais pas à l'avance si la commande doit s'éxécuter pour la première itération.
    Dans ce cas, il faut utiliser un while à la place du do/while.

  10. #10
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2012
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Spartacusply Voir le message
    Je pense que tu t'y prends mal avec ton tableau classe. Je pense que ton algo peut-être amélioré.

    Par étape ça pourrait donner :

    - Tu récupères la liste des notes
    - Tu récupères la liste des devoirs
    - Tu récupère la liste des élèves
    - Pour chaque élève (et tu ne remplis ta variable classe qu'à ce moment là) :
    - Tu créé l'élément dans le tableau classe
    - Pour chaque devoir :
    - S'il existe une note pour l'élève pour ce devoir, tu la rajoutes, sinon tu mets ""

    Et voilà, simple et efficace.

    PS : évite les références aussi juste quand il s'agit de "simplification d'écriure", elle ne sont pas prévues pour ça et risque plus de t'embrouiller qu'autre chose au final
    Spartacusply tout d'abord merci pour ta réponse. J'ai essayé comme ça pas à pas et en effet c'est beaucoup plus clair et ça fonctionne...enfin presque.
    Il manque un détail et j'ai beau essayé de toute les manières il ne se solutionne pas.

    J'ai donc procédé de cette manière :

    Pour chaque élève je créé un nombre d'array(devoir) déterminé à l'avance (sans encore savoir s'il y a participé), et ce, afin que l'élément existe par cohérence avec les autres élèves qui y ont eux partcicipé.

    Ensuite je boucle sur ma requête et à chaque note trouvée, je souhaite mettre à jour l'array correspondant du devoir et y insérer les notes. Cela me semblait logique mais ça bloque.
    j'ai donc fait plusieurs tests:
    Si je ne créé pas de suite les arrays vides mais boucle directement sur ma requête, il me crée bien les arrays auxquels l'élève a participé mais pas ceux auxquels il n'était pas présent (et ok c'est logique).

    Mais si je créé d'abord les arrays vides et boucle ensuite sur ma requête, il ne modifie pas les devoirs pour y insérer les notes et avec un print_r je vois que tout est créé mais vide.

    Voici mon code:

    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
    24
    25
    26
    27
    28
    29
    <!DOCTYPE html>
     
    <link rel="stylesheet" type="text/css" href="global.css">
     
    <?php
     
    $bdd = new PDO('mysql:host=localhost;dbname=test19_11', 'root', '', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    $requete = $bdd->prepare('SELECT * FROM `voti`  ORDER BY `Nom_Eleve` ASC');
    $requete->execute(); 
     
     
    $data = array();
    $tous = array();
     
    while ($data = $requete->fetch(PDO::FETCH_ASSOC)){
    	$tous[$data['Nom_Eleve']] = array(1=>array(),2=>array());
    }
    $requete->closeCursor();
     
    while ($data = $requete->fetch(PDO::FETCH_ASSOC))
     
    {		
     $tous[$data['Nom_Eleve']][$data['Num_Devoir']]  = $data ;	    
     
    }
     
    echo '<pre>';
    print_r($tous); 
    echo '</pre>';
    La ligne " $tous[$data['Nom_Eleve']][$data['Num_Devoir']]" est donc censée correspondre à '$tous[$data['Nom_Eleve']]' + 1 ou 2 ou 18 etc...
    Comme chacune des méthodes fonctionne mais séparemment, n'y a-t-il pas un problème au moment de modifier l'array existant en y insérant les données ?

    Je tourne en rond et ne comprend pas l'erreur..
    merci

    P.S. Merci aussi à Celira

  11. #11
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 275
    Points
    3 275
    Par défaut
    Déjà on ne peut pas fetcher une requête deux fois de suite. Il ne rentre donc jamais dans ta deuxième boucle (et de toutes façons c'est mauvais pour les performances). De plus, je croyais que tu avais une table élève, une table devoir et une table vote qui fait la liaison entre les deux (c'est ce qui faudrait faire dans une bdd de données propre et conventionnelle).

    Autre remarque EXTREMEMENT importante : l'index d'un tableau commence à l'indice 0, et non 1 !

    Après si tu n'as qu'une seule table, on peut se débrouiller autrement :

    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
    $bdd = new PDO('mysql:host=localhost;dbname=test19_11', 'root', '', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    $requete = $bdd->prepare('SELECT * FROM `voti`  ORDER BY `Nom_Eleve` ASC');
    $requete->execute();
     
    $notes = $requete->fetchAll(PDO::FETCH_ASSOC);
     
    $devoirs = array_unique(array_column($notes, 'Num_Devoir'));
    $eleves = array_unique(array_column($notes, 'Nom_eleve'));
     
    $classe = [];
    foreach ($eleves as $eleve) {
        foreach ($devoirs as $devoir) {
            $noteDevoir = '';
            foreach ($notes as $note) {
                if ($note['Num_devoir'] == $devoir AND $note['Nom_eleve'] == $eleve) {
                    $noteDevoir = $note['Note'];
                    break;
                }
            }
            $classe[$eleve][$devoir] = $noteDevoir;
        }
    }

Discussions similaires

  1. Modifier un numpy array dans une fonction ?
    Par Kaluza dans le forum Général Python
    Réponses: 2
    Dernier message: 05/03/2013, 14h53
  2. MovieClip avec nom dynamique
    Par quakebest dans le forum Dynamique
    Réponses: 1
    Dernier message: 29/10/2007, 20h17
  3. Récupérer checkbox avec nom dynamique
    Par dumser1 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 24/04/2007, 12h02
  4. checked d'un checkbox avec nom dynamique
    Par Sylvain245 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 11/11/2005, 12h28
  5. [syntaxe]Creation table avec nom dynamique
    Par ZuZu dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 23/09/2004, 19h01

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