Doublon dans un array ?
Résolu
emrh
Messages postés
427
Date d'inscription
Statut
Membre
Dernière intervention
-
emrh Messages postés 427 Date d'inscription Statut Membre Dernière intervention -
emrh Messages postés 427 Date d'inscription Statut Membre Dernière intervention -
Bonjour à tous,
J'ai du mal à comprendre les array ce qui fait que je n'obtiens pas ce que je veux
avec ma programmation...
Voici une requête qui fonctionne bien dans PhpMyAdmin :
résultat obtenu :
Mais qui ne donne pas le résultat escompté en php :

Pourriez vous m'aider à résoudre ce double affichage des factures ?
D'avance merci !
J'ai du mal à comprendre les array ce qui fait que je n'obtiens pas ce que je veux
avec ma programmation...
Voici une requête qui fonctionne bien dans PhpMyAdmin :
SELECT contrats.facture, SUM(T.total) AS Total_facture FROM (SELECT id_contrat,prix*quantites AS total FROM compositions) AS T INNER JOIN contrats ON contrats.id_contrat = T.id_contrat WHERE contrats.facture <> 'NULL' AND contrats.id_client =18 GROUP by contrats.facture
résultat obtenu :

Mais qui ne donne pas le résultat escompté en php :
// Récupération des factures du client sélectionné : $requete_factures = $bdd->prepare(' SELECT contrats.facture, contrats.date_facture, contrats.id_contrat FROM contrats WHERE contrats.id_client = :id_client AND contrats.etat = 3 ORDER BY contrats.facture DESC'); $requete_factures->execute(array('id_client' => $_GET['id_client'])); $nbr_factures = $requete_factures->rowCount(); // Calcul du total par facture : $requete_totaux_factures = $bdd->prepare(" SELECT contrats.facture, SUM(T.total) AS Total_facture FROM (SELECT id_contrat,prix*quantites AS total FROM compositions) AS T INNER JOIN contrats ON contrats.id_contrat = T.id_contrat WHERE contrats.facture <> 'NULL' AND contrats.id_client = :id_client GROUP by contrats.facture"); $requete_totaux_factures->execute(array('id_client' => $_GET['id_client'])); $totauxparfactures = $requete_totaux_factures->fetchAll(); // On stock les n° de factures et leurs totaux correspondant dans un array $total : $total_facture=array(); foreach($totauxparfactures as $valeur) { $total_facture[$valeur['facture']] = $valeur['Total_facture']; } <tbody> <?php while ($data_facture = $requete_factures->fetch()) { ?> <tr> <td> <?php echo $data_facture['facture']; ?> </td> <td class="td-gauche"> <?php $date_facture = date("d/m/Y", strtotime($data_facture['date_facture'])); echo $date_facture; ?> </td> <td class="td-droite"> <?php $total = $total_facture[$data_facture['facture']]; echo number_format($total, 2, ',', ' ');?> </td> </tr> <?php }?> </tbody>

Pourriez vous m'aider à résoudre ce double affichage des factures ?
D'avance merci !
Configuration: Linux / Chrome 99.0.4844.84
A voir également:
- Doublon dans un array ?
- Doublon photo - Guide
- Supprimer doublon excel - Guide
- Logiciel doublon photo gratuit - Télécharger - Nettoyage
- Supprimer doublon word ✓ - Forum Word
- Excel rang sans doublon ✓ - Forum Bureautique
1 réponse
Bonjour,
Et ensuite, dans ton code html, là où tu veux t'en servir :
<?php // NB: Code à placer AU DEBUT de ton script PHP .. pas en plein milieu de ton code html comme // il semble que ça soit le cas actuellement !! //---------------------------------------------------------------// //connexion à la bdd // A lire et à appliquer avant de poursuivre : // http://www.commentcamarche.net/faq/46512-pdo-gerer-les-erreurs //---------------------------------------------------------------// //---------------------------------------------------------------// // On va découper ton code en "fonctions" // ça le rendra plus lisible et plus facile // à maintenir ou à faire évoluer //---------------------------------------------------------------// function getNbFacturesById_Client($id_client){ global $bdd; $sql = "SELECT count(*) AS NB FROM contrats WHERE contrats.id_client = :id_client AND contrats.etat = 3"; try{ $stmt = $bdd->prepare($sql); $stmt->execute(array(':id_client' => $id_client)); $resultat = $stmt->fetchColumn(); // https://www.php.net/manual/fr/pdostatement.fetchcolumn.php return $resultat; }catch(Exception $e){ echo "Erreur dans la requête " . $sql; echo $e->getMessage(); exit; } } function getFacturesById_Client($id_client){ global $bdd; $sql = "SELECT contrats.facture , SUM(T.total) AS TOTAL_FACTURE , DATE_FORMAT(contrats.date_facture, '%d/%m/%Y) as DATE_FACTURE_FR FROM ( SELECT id_contrat,prix*quantites AS total FROM compositions ) AS T INNER JOIN contrats ON contrats.id_contrat = T.id_contrat WHERE contrats.facture <> 'NULL' AND contrats.id_client = :id_client GROUP by contrats.facture"; try{ $stmt = $bdd->prepare($sql); $stmt->execute(array(':id_client' => $id_client)); $resultat = $stmt->fetchAll(); //On retourne un Array du résultat return $resultat; }catch(Exception $e){ echo "Erreur dans la requête " . $sql; echo $e->getMessage(); exit; } } //---------------------------------------------------// // On récupère proprement les variables envoyées // en $_POST / $_GET / $_SESSION ... AVANT de les utiliser // pour cela, j'utilise l'écriture ternaire : https://blog.smarchal.com/operateur-ternaire-php#:~:text=L'op%C3%A9rateur%20ternaire%20est%20un,%5BTHEN%5D%20%3A%20%5BELSE%5D%3B //---------------------------------------------------// $id_client = !empty($_GET['id_client']) ? trim($_GET['id_client']) : NULL; // On récupère les données en bdd $nbFactures = getNbFacturesById_Client($id_client); // nombre de facture pour le client et en etat 3 ( tu ne t'en sers pas ? ) $arrFactures = getFacturesById_Client($id_client); // array contenant la liste de tes factures ?>
Et ensuite, dans ton code html, là où tu veux t'en servir :
<tbody> <?php foreach( $arrFactures as $F ) { ?> <tr> <td> <?php echo $F['facture']; ?> </td> <td class="td-gauche"> <?php echo $F['DATE_FACTURE_FR']; ?> </td> <td class="td-droite"> <?php $total = $total_facture[$F['TOTAL_FACTURE']]; echo number_format($total, 2, ',', ' '); ?> </td> </tr> <?php } ?> </tbody>
Merci Jordan pour cette longue explication que je vais décortiquer pour comprendre comment tu codes
et m'en inspirer...
// NB: Code à placer AU DEBUT de ton script PHP .. pas en plein milieu de ton code html comme
// il semble que ça soit le cas actuellement !!
Non, non, je t'assure, mon code php est bien écrit en début de page et mon JavaScript en fin de page...
D'ailleurs je me demande pourquoi écrire des fonctions en début de code (qui obligent l'utilisation de global $bdd; par exemple) si on peut récupérer au même endroit les variables d'URL (ou de formulaires) puis lancer les requêtes dans la foulée ?
Tu dis que c'est pour la lisibilité et la maintenance alors que je pensais que des blocs d'instructions comme
ça étaient tout aussi faciles à lire et maintenir :
L'utilisation de $stmt est certainement plus pro et propre que $requete_totaux_factures
mais quand on peine avec le code, il me semblait que c'était plus lisible d'utiliser des variables claires plutôt qu'abstraites. D'autre part, je suis souvant coincé par le nom de variables utilisées plus loin dans le code comme $facture, c'est pour ça que pour éviter des plantages j'utilise ce type de noms de requêtes...
Je suis prêt à passer en pro mais je me demande quelle peut être l'utilité de rendre le code plus concis ? C'est comme l'écriture ternaire que j'ai utilisé une fois ou deux mais, par manque d'habitude, je la trouve moins simple à lire...
C'est comme les foreach : ou les endif : qui ont fait disparaître les } ...ça doit être une question d'habitude !
//connexion à la bdd .../... pdo-gerer-les-erreurs
Ma page connexion.php me semblait correcte non ?
SELECT count(*) AS NB...
$nbr_contrats = $requete_contrats->rowCount(); me semblait pourtant pas mal pour le/les comptages...
Tu me déconseilles son utilisation ?
fetchColumn();
Je vais jeter un œil là dessus, bien que j'ai toujours pensé que la doc de php.net s'adressait à des pros : elle m'est extrêmement difficile à lire et à comprendre... Mais j'ai bien conscience que je vais devoir y passer pour obtenir les
résultats de plus en plus complexes que je souhaite obtenir (tout comme les FetchAll(PDO:: ...etc que je ne sais toujours pas utiliser !)
Je peux donc appeler toutes les miennes $requete et n'utiliser qu'un seul closeCursor(); ?
- J'ai corrigé ' dans DATE_FORMAT(contrats.date_facture, '%d/%m/%Y)
- Pour quelle raison tu utilises des champs en majuscules comme DATE_FACTURE_FR et tu laisses les
autres en minuscules ? Devrais-je pour des raisons de normalisation utiliser des majuscules pour le
nom de mes champs en bdd ?
- Comment lire en français cette ligne :
$id_client = !empty($_GET['id_client']) ? trim($_GET['id_client']) : NULL;
Voilà ce que je comprends :
Variable id_client = SI (elle n'est pas vide) ALORS ???? supprimer les espaces de id_client ? SINON id_client n'existe pas
- Toutes mes requêtes fonctionnent avec
execute(array('id_client' => $_GET['id_client']));
à quoi sert le : que tu ajoutes dans
execute(array(':id_client' => $_GET['id_client']));
:-)
Merci JORDAN !!!
A la place, on fera une requête avec un count ou alors un fetchAll (sur lequel on fera un count en php )
Pour ce qui est du découpage en fonctions ( fonctions que tu pourrais mettre dans un autre fichier et l'inclure dans les pages où tu en as besoin) c'est avant tout pour éviter de réécrire plusieurs fois le même code dans différentes pages.
J'aurai pu aller encore plus loin ( ce que je fais souvent ) en découpant en CLASS ( histoire de passer à la notion d'objet )
Oui bien sûr.
A noter que le closeCursor n'est pas nécessaire en mysql.
En BDD je nomme toujours mes tables et mes champs en minuscule.
Par contre, dans les requête, lorsque je mets des ALIAS, là je les met en majuscule. ( ça me permet de différencier les champs qui proviennent directement de ma bdd avec ceux que j'ai éventuellement manipulé )
Il n'y a aucune obligation à le faire.
Tout à fait.
Les deux points, c'est pour être conforme au "nommage" de la variable que tu mets dans tes requêtes
A noter que tu n'utiliseras plus, désormais, $_GET['tavariable'] dans ton exécute ... mais tu auras, au préalable récupéré proprement la variable AVANT de l'utiliser.