Stockage données BDD dans un array associatif multidimensionnel

Résolu/Fermé
emrh
Messages postés
345
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
20 septembre 2022
- Modifié par emrh le 27/06/2016 à 14:26
mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
- 28 juin 2016 à 11:43
Bonjour à tous,

J'ai aujourd'hui une page php qui affiche parfaitement dans une table html les données en provenance d'une base de donnée Mysql.
Ces données sont des chiffres d'affaires rangés ainsi :
id_ca (ex : 01)
mois_ca (ex : 06)
annee_ca (ex: 2016)
chiffre_ca (ex : 123456)

J'ai décidé de transformer cette page pour utiliser PDO (et travailler plus tard avec l'objet DateTime). Malheureusement, la commande mysql_data_seek($sql2,0); que j'utilisais avant et qui me permettait de remettre le pointeur au début et faire en sorte que ma boucle "for" classe toutes mes données dans l'ordre ne fonctionne plus !

On me conseille plutôt qu'une usine à gaz de "if" imbriqués dans des boucles "for"
de récupérer mes données dans un array associatif et de travailler avec l'array plutôt que des accès réguliers à la bdd...

Voici donc ce que j'ai pu écrire avec de l'aide trouvée sur un autre forum :


// Déclaration tableau
$ca = array();
// Requète :
$sql = 'SELECT * from chiffreaffaire';
// Exécution :
$req = $DB->query($sql);
// Récupération données :
$donnees = $req->fetchAll(PDO::FETCH_ASSOC);
// Affectation des données récupérées dans un tableau
foreach($donnees as $row){
$ca[$row['annee_ca']] = array(
'mois'=>$row['mois_ca'],
'ca'=>$row['chiffre_ca']
);
}

// Appel d'un enregistrement :
echo 'Un enregistrement au hasard : ' . '<br />';
echo 'Mois : ' . $ca[2010]['mois'] . '<br />';
echo 'Chiffre d\'affaire : ' . $ca[2010]['ca'] . '<br />';


// Vérification de la totalité des enregistrements :
echo '<br />' . 'Tableau complet : ' ;
echo '<pre>';
print_r($ca);
echo '</pre>';




die();


Le problème est que le tableau complet fait 12 lignes au lieux de 150 et que je n'enregistre dans cet array que le dernier mois comme valeur !

RÉSULTAT :
Un enregistrement au hasard :
Mois : 12
Chiffre d'affaire : 31806

Tableau complet :

Array
(
[2001] => Array
(
[mois] => 12
[ca] => 9078
)

[2002] => Array
(
[mois] => 12
[ca] => 32813
)


Etc...

Si vous aviez un idée, je suis preneur et vous en remercie d'avance :-)

7 réponses

mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
99
27 juin 2016 à 14:25
Tu ne peux pas trier directement dans la requête SQL ?

--
1
emrh
Messages postés
345
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
20 septembre 2022
7
Modifié par emrh le 27/06/2016 à 14:32
J'ai un double tri : par année puis par mois pour ensuite totaliser les chiffres d'affaires...

Au départ j'ai un formulaire dans lequel je sélectionne (select) l'année, puis le mois (select) et je saisis le chiffre d'affaire (input)...
si le ca (chiffre d'affaire) n'existait pas, il est créé, sinon il est modifié !

Je dois ensuite revenir sur une page qui m'affiche un grand tableau (table html) qui m'ordonne tout ça !
0
mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
99
27 juin 2016 à 14:38
Ok, mais ici tu ne fais que l'affichage, tu pourrais ajouter un :
order by annee desc, mois desc

Tu aurais ainsi en résultat : 2016-06 / 2016-05 / .. / 2015-12 / 2015-11..

Sinon, si tu veux conserver ta méthode actuelle, il faut (je pense, je suis pas un expert) faire autrement.
Car actuellement, tu boucles sur toutes les lignes, mais tu n'as qu'un array par année.
Du coup $ca[$row['annee_ca']] contient toujours le dernier mois..

Je pense qu'il vaut mieux faire

foreach($donnees as $row){
$ca[$row['annee_ca']]['mois'] = $row['mois_ca'];
$ca[$row['annee_ca']]['ca'] = $row['chiffre_ca']
}

--
0
emrh
Messages postés
345
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
20 septembre 2022
7
Modifié par emrh le 27/06/2016 à 16:10
Tu as tout à fait raison : je vais opter pour la première solution, je ne
savais même pas que l'ont pouvait faire 2 tris ! ! !
J'ai fait un essai avec un print_r et ça fonctionne !

Alors maintenant, comment ranger tout ça dans une table html ?

Voici mon code précédent : il reste désespéramment vide !

<?php
$sql2 = $DB->query('SELECT * from chiffreaffaire ORDER BY annee_ca desc, mois_ca desc');
?>

<tbody> <!-- Corps du tableau -->
<?php
// Déclaration de l'array 'mois' :
$mois = array('JANVIER','FEVRIER','MARS','AVRIL','MAI','JUIN','JUILLET','AOUT','SEPTEMBRE','OCTOBRE','NOVEMBRE','DECEMBRE');

// Déclaration des array totaux annuels :
$total= array();

for ($m=1; $m<13; $m++){
$total[$annee] = '0';
?><tr>
<td align="left"> <?php echo $mois[$m-1]; ?> </td><?php

for ($annee=2018; $annee>2009;--$annee) {?>
<td align="right"><?php
while ($data = $sql2->fetchAll(PDO::FETCH_ASSOC)){
if ($data['annee_ca']==$annee && $data['mois_ca']==$m){
$total[$annee]= $total[$annee]+$data['chiffre_ca'];
echo number_format($data['chiffre_ca'], 2, ',', '.');
}
}
echo ' ' . '</td>';
}
}?>
</tbody>

<tfoot> <!-- Pied de tableau -->
<th>TOTAUX</th>
<th align="right"><?php echo number_format($total[2009], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2008], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2007], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2006], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2005], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2004], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2003], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2002], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2001], 2, ',', '.') . ' '; ?></th>
</tfoot>




Edit : while ($data = $sql2->fetch()){ modifié en
while ($data = $sql2->fetchAll(PDO::FETCH_ASSOC)){
0
mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
99
27 juin 2016 à 16:05
Pourquoi tu refetchs tes données dans le tableau ?

Déjà, ton tableau sera bizarre : tu auras
janvier 2018
janvier 2017
...
janvier 2010
février 2018
février 2017.
...

C'est voulu ?

Enfin, une fois ton while passé une première, je suis pas sur qu'il puisse re-fetcher..

C'est quoi ce que tu attends comme tableau ? :)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
emrh
Messages postés
345
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
20 septembre 2022
7
Modifié par emrh le 27/06/2016 à 17:49
Je ne sais pas ce que c'est "refetchs"...
EDIT : En fait le bout de code du premier post c'était pour ne pas avoir à tout poster... Mais je ne "fetch" qu'une fois :-)

En tous cas, voici ce qui fonctionne actuellement, sans PDO :




C'est ce bout de code qui n'est pas compatible de PDO :
mysql_data_seek($sql2,0);

Cette fonction me sert à remettre le pointeur au début et reparcourir
la BDD à la recherche de la correspondance suivante : j'ai conscience
qu'en terme de perf. c'est très mauvais !

Voila le code complet qui fonctionne, mais pas en PDO :

<h2>EVOLUTION DU CHIFFRE D'AFFAIRES :</h2>
<span style ="color : red;"><em><?php echo "Mise à jour le " . $maj ?></em></span>
<!-- En PHP : //date ("d m Y à H:i:s", getlastmod()); -->
<table>
<thead> <!-- En-tête du tableau -->
<th width="80px">Mois</th>
<th width="100px">2018</th>
<th width="100px">2017</th>
<th width="100px">2016</th>
<th width="100px">2015</th>
<th width="100px">2014</th>
<th width="100px">2013</th>
<th width="100px">2012</th>
<th width="100px">2011</th>
<th width="100px">2010</th>
</thead>

<tbody> <!-- Corps du tableau -->
<?php
// Déclaration de l'array 'mois' :
$mois = array('JANVIER','FEVRIER','MARS','AVRIL','MAI','JUIN','JUILLET','AOUT','SEPTEMBRE','OCTOBRE','NOVEMBRE','DECEMBRE');

// Déclaration des array totaux annuels :
$total= array();

for ($m=1; $m<13; $m++){
$total[$annee] = '0';
?><tr>
<td align="left"> <?php echo $mois[$m-1]; ?> </td><?php

for ($annee=2018; $annee>2009;--$annee) {?>
<td align="right"><?php
while ($data = mysql_fetch_array($sql2)){
if ($data['annee_ca']==$annee && $data['mois_ca']==$m){
$total[$annee]= $total[$annee]+$data['chiffre_ca'];
echo number_format($data['chiffre_ca'], 2, ',', '.');
}
}
echo ' ' . '</td>';
mysql_data_seek($sql2,0);
}
}?>
</tbody>

<tfoot> <!-- Pied de tableau -->
<th>TOTAUX</th>
<th align="right"><?php echo number_format($total[2018], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2017], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2016], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2015], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2014], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2013], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2012], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2011], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2010], 2, ',', '.') . ' '; ?></th>
</tfoot>
</table>
<br />
0
mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
99
Modifié par mrjenkins le 27/06/2016 à 21:52
Ok.

Dans ta DB, tu as plusieurs enregistrements pour une même date ?
Genre :
2015-04 : 10 000
2016-01 : 25 000
2015-04 : 12 000
?

Ou les années/mois sont uniques ?
Si c'est unique : pas besoin de s'embêter, tu fais un simple :

for ($m=1; $m<13; $m++){
?><tr>
<td align="left"> <?php echo $mois[$m-1]; ?> </td><?php

for ($annee=2018; $annee>2009;--$annee) {?>
<td align="right"><?php
echo number_format($ca[['annee']]['ca'], 2, ',', '.');
echo ' ' . '</td>';
mysql_data_seek($sql2,0);
}
}?>


(avec $ca initialisé comme plus haute avec un fetchAll(PDO::FETCH_ASSOC))

Si ce n'est pas unique, tu peux encore améliorer le SQL :

SELECT mois, annee, sum(ca) as total_ca
FROM chiffreaffaire
GROUP BY annee, mois
ORDER BY annee desc, mois asc
0
emrh
Messages postés
345
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
20 septembre 2022
7 > mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018

Modifié par emrh le 28/06/2016 à 00:29
Déjà merci mrjenkins de te donner tout ce mal pour l'aider !

Un mois ne pouvant avoir qu'un seul chiffre d'affaire, je n'ai pas plusieurs 2015-04 avec
des chiffres d'affaires différents ! ;-)

D'autre part, ton code pour un mois unique ne peut s'adapter : il contient mysql_data_seek($sql2,0); et c'est justement l'instruction qui m'a fait rédiger ce post car incompatible avec PDO !

Voici l'aide que j'ai reçu d'Advancid sur un autre forum... J'obtiens bien un array dont l'indice principal est l'année. Cet indice peut contenir les 2 mois de l'année et chaque mois possède son chiffre d'affaire...


// EXERCICE
// Déclaration tableaux :
$donnees = array();
$total = array();

// Requète :
$sql = 'SELECT * from chiffreaffaire';

// Exécution :
$req = $DB->query($sql);

// Récupération données :
$resultat = $req->fetchAll(PDO::FETCH_ASSOC);

// Affectation des données récupérées dans un tableau associatif multiple :
foreach($resultat as $donnee) {
$annee = $donnee['annee_ca'];
$mois = $donnee['mois_ca'];
$chiffreAffaire = $donnee['chiffre_ca'];

if (!array_key_exists($annee, $donnees)) {
$donnees[$annee] = array();
}

if (!array_key_exists($annee, $total)) {
$total[$annee] = 0;
}

$total[$annee] += $chiffreAffaire;
$donnees[$annee][$mois] = $chiffreAffaire;
}

//Vérification :
var_dump($donnees);

die();

Pour l'instant je ne comprends pas les 2 derniers if ainsi que le += dans le calcul total du chiffre d'affaire, mais ça fonctionne...

Je vais chercher comment adapter mon code pour la mise en place des ces chiffres d'affaire dans ma table html !
0
mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
99
28 juin 2016 à 08:31
Pas de souci =)

Ca ressemble grosso modo à ce que j'avais en tête, mais en mieux fait ^^

Les 2 if permettent d'initialiser les tableaux lors du 1er passage de l'année dans la boucle.
Et le += permet de faire le total sur l'année.

Ici, il te fait 2 tableaux :
1. $donnees[$annee][$mois] qui te donne le CA du mois
2. $total[$annee] qui te donne le CA de l'année
0
emrh
Messages postés
345
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
20 septembre 2022
7
Modifié par emrh le 28/06/2016 à 09:06
Merci pour tes explications...

Hier j'ai posté un peu tard et le copier/coller de mon code était un essai de ré écriture... Il comporte des erreurs entres $donnée et $donnees notamment !

Voici celui d'origine qui fonctionne :


$requete=$DB->query("SELECT * from chiffreaffaire");
$resultatRequete = $requete->fetchAll(PDO::FETCH_ASSOC);
$donnees = array();
$total = array();

foreach($resultatRequete as $donnee) {
$annee = $donnee['annee_ca'];
$mois = $donnee['mois_ca'];
$chiffreAffaire = $donnee['chiffre_ca'];

if (!array_key_exists($annee, $donnees)) {
$donnees[$annee] = array();
}

if (!array_key_exists($annee, $total)) {
$total[$annee] = 0;
}

$total[$annee] += $chiffreAffaire;
$donnees[$annee][$mois] = $chiffreAffaire;
}

//Vérification :
var_dump($donnees);

die();



Le var_dump me donne ça maintenant :
array(16) { [2001]=> array(6) { [8]=> string(6) "123456" [7]=> string(6) "123456" [9]=> string(6) "123456" [10]=> string(6) "123456" [11]=> string(6) "123456" [12]=> string(6) "123456" }
pour la première année, donc c'est tout bon (elle n'était pas complète)...
On voit bien que chaque indice correspond à un mois avec à chaque début le millésime...

Maintenant je suppose que le meilleur moyen de remplir une table html de ces données et d'utiliser une boucle FOR non ?


EDIT : Je viens de faire un essai avec le même code mais avec :
$resultatRequete = $requete->fetchAll();

au lieu de ça :

$resultatRequete = $requete->fetchAll(PDO::FETCH_ASSOC);

et le résultat affiché au var_dump est le même !
0
mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
99
28 juin 2016 à 09:06
2 boucles for imbriquées oui : tu boucles sur les annèes, puis sur les mois.. et tu fais un echo de $donnees[$annee][$mois]

Et ça devrait rouler =)
0
emrh
Messages postés
345
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
20 septembre 2022
7
Modifié par emrh le 28/06/2016 à 11:43
Encore merci de ton aide mrjenkins
Et voila l'travail :


// Connexion à la base de donnée :
require_once('connexion.php');

$requete=$DB->query("SELECT * from chiffreaffaire");
$resultatRequete = $requete->fetchAll();
$donnees = array();
$total = array();
// Déclaration de l'array 'mois' :
$mois_tableau = array('NULL','JANVIER','FEVRIER','MARS','AVRIL','MAI','JUIN','JUILLET','AOUT','SEPTEMBRE','OCTOBRE','NOVEMBRE','DECEMBRE');

foreach($resultatRequete as $donnee) {
$annee = $donnee['annee_ca'];
$mois = $donnee['mois_ca'];
$chiffreAffaire = $donnee['chiffre_ca'];

if (!array_key_exists($annee, $donnees)) {
$donnees[$annee] = array();
}

if (!array_key_exists($annee, $total)) {
$total[$annee] = 0;
}

$total[$annee] += $chiffreAffaire;
$donnees[$annee][$mois] = $chiffreAffaire;
}

.../...


<tbody> <!-- Corps du tableau -->
<?php
for ($m=1; $m<13; $m++) { ?>
<tr>
<td align="left">
 <?php echo $mois_tableau[$m]; ?> 
</td><?php
for ($an=2018; $an>2009;--$an) {?>
<td align="right">
<?php echo number_format($donnees[$an][$m], 2, ',', '.') . ' ';?>
</td><?php
}?>
</tr><?php
}
?>
</tbody>



<tfoot> <!-- Pied de tableau -->
<th>TOTAUX</th>
<th align="right"><?php echo number_format($total[2018], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2017], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2016], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2015], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2014], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2013], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2012], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2011], 2, ',', '.') . ' '; ?></th>
<th align="right"><?php echo number_format($total[2010], 2, ',', '.') . ' '; ?></th>
</tfoot>


0
mrjenkins
Messages postés
577
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
17 juillet 2018
99
28 juin 2016 à 11:43
Y a pas de quoi ;)
0