Bonjour à tous, j'ai cherché sur le forum, sur les tutoriels, je veux juste afficher le résultat de ma commande sql sous forme de tableau sur ma page html, comme elle s'affiche sur mon interface de DB, simplement. Sans succès.
J'ai réussi à faire une partie, j'ai ma première collone comme il faut, mais la seconde ne m'affiche qu'une seule cellule, je sait qu'il y a un problème sur la boucle mais je n'arrive pas à trouver où.
Je pensais vraiment trouver un tutoriel qui explique comment retourner un résultat sql sous forme de tableau identique, mais j'ai pas trouvé sur openclassroom, dommage...
bref voici le code:
<div id="content">
<h3>CLASSEMENT JOUEURS (période actuelle)</h3>
<?php
$sql = "SELECT _owner,COUNT(*) FROM `creatures` GROUP BY _owner";
$req = $dbh->query($sql);
$req->setFetchMode(PDO::FETCH_ASSOC);
while($row = $req->fetch()) $rows[$ligne++] = $row;
foreach( array('_owner') as $champJ ){
?><table><tr><td>Joueur</td><td>Créatures</td></tr><?php
foreach( array('COUNT(*)') as $champ ){
foreach( $rows as $row )
echo "<tr><td>".$row[$champJ]."</td>";
echo "<td>".$row[$champ]."</td>";
?></tr><?php
}}
$req->closeCursor();
?>
<br>
</div>
COUNT() est une fonction interne en SQL, ça retourne un nombre, ici, COUNT(*) retourne le nombre total de lignes dans la table "creatures", puisque l'étoile "*" veut dire "tout", donc toutes les colonnes de la table.
Ah, je croyais que tu parlais de la requête sql, j'ai pas vu ça, et je me demande même si ça fonctionne ? Parce que la boucle foreach, dans ce cas précis, sert à parcourir le résultat de la requête, COUNT() est réservé à sql et il est déjà utilisé dans la requête.
Pour générer un tableau dynamiquement :
<?php
$sql = "SELECT _owner joueur,COUNT(*) tot FROM `creatures` GROUP BY _owner";
$req = $dbh->query($sql);
$result = $req->fetchAll(PDO::FETCH_ASSOC);
// Tu peux rajouter ici les résultats de tes requêtes, si tu as fait plusieurs requêtes.
// Il s'agit ici d'un tableau à trois dimensions, c'est un tableau de tableaux.
$arrays = [
$result
];
?>
Pour générer dynamiquement un tableau html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<?php foreach ($arrays as $array): ?>
<?php if ( empty($array) ): // Si la requête SQL ne renvoie pas de résultat. ?>
<?php strip_tags("<table>"); // Il n y a pas besoin de tableau HTML ?>
<?php else: ?>
<div class="content">
<table>
<thead>
<tr>
<?php
/* Cette condition ne sert pas à vérifier si la requête
SQL a bien renvoyé un résultat, la condition du if qui
se trouve juste au-dessus - if ( empty($array) ): - s'en
occupe déjà. La présente condition teste le nombre d'éléments
présents dans le tableau. C'est pour ça que le présent if
n'a pas besoin d'un else. Le test de ce if permet à ensuite,
à la ligne suivante, de récupérer une clé - array_keys($array[0]) -
grâce à la l'utilisation de la fonction count(). */
if ( count($array) ):
?>
<?php
/* ici, on ne cherche pas à récupérer les valeurs de
la première ligne du tableau - $array[0] - mais plutôt
les clés de ces valeurs - array_keys($array[0]) - pour
pouvoir créer les noms des colonnes dynamiquement. */
$columns_names = array_keys($array[0]);
?>
<?php foreach($columns_names as $column_name): ?>
<th class="shadow"><?= $column_name; ?></th>
<?php endforeach; ?>
<?php endif; ?>
</tr>
</thead>
<tbody>
<?php foreach($array as $row): ?>
<tr>
<?php foreach($row as $value): ?>
<td><?= ( empty($value) ) ? "NULL" : $value; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
</body>
</html>
@julp, est-ce que ton message m'est destiné ? Si c'est le cas, montres-moi un code dans ce post (ou sinon d'autre part) qui permet de générer un tableau dynamiquement avec une seule boucle. Je n'ai pas réécris fetchAll, il n'est écrit qu'une seule fois, pas deux.
La différence, c'est que ta méthode ne permet pas de générer un tableau dynamiquement, tu dois mettre autant de th/td qu'il y a de colonnes dans le tableau, et autant de tr qu'il y a de lignes. Avec mon code, il suffit de mettre une seule balise tr, une seule balise th et une seule balise td et le tout est généré dynamiquement. Alors c'est sûr que pour un petit tableau, l'intérêt n'est pas évident, mais imagines un tableau avec 20 colonnes et 1000 lignes, il faudrait mettre 1000 tr, 20 th et 20 000 td, hum, il y a mieux. Et les boucles foreach sont mieux adaptées aux tableaux que les boucles while. Ensuite, pour un seul tableau, il suffit d'une seule boucle pour les th (entête) et deux boucles pour les td. Si il y a une quatrième boucle, c'est une boucle générale qui englobe les trois autres au cas où il y aurait plusieurs tableaux, ce qui est matéralisé ici par le tableau $arrays.
<?php
$sql = "SELECT _owner joueur,COUNT(*) tot FROM `creatures` GROUP BY _owner";
$req = $dbh->query($sql);
$result1 = $req->fetchAll(PDO::FETCH_ASSOC);
$sql = "SELECT _owner joueur,COUNT(*) tot FROM `creatures` GROUP BY _owner";
$req = $dbh->query($sql);
$result2 = $req->fetchAll(PDO::FETCH_ASSOC);
$sql = "SELECT _owner joueur,COUNT(*) tot FROM `creatures` GROUP BY _owner";
$req = $dbh->query($sql);
$result3 = $req->fetchAll(PDO::FETCH_ASSOC);
// Tu peux rajouter ici les résultats de tes requêtes, si tu as fait plusieurs requêtes.
// Il s'agit ici d'un tableau à trois dimensions, c'est un tableau de tableaux.
$arrays = [
$result1, $result2, $result3
];
?>
De plus, ton code ne suit pas les bonnes pratiques et n'est pas très flexible, tu crées le tableau, et c'est à l'intérieur du tableau que tu récupères les résultats de la requête et que tu les injectes dans le tableau. Il vaut mieux séparer les deux. D'abord, récupérer les résultats de la requête, ensuite seulement, créer le tableau et injecter les résultats à l'intérieur du tableau. Procéder de cette manière permet de se diriger doucement vers le pattern mvc et la poo qui est plus flexible et plus maintenable et évolutive.
> La différence, c'est que ta méthode ne permet pas de générer un tableau dynamiquement
Si ce n'est que ça, je te change la boucle while pour itérer sur les noms des colonnes ou, mieux, je ta rajoute "un" PDOStatement::getColumnMeta.
> les boucles foreach sont mieux adaptées aux tableaux que les boucles while
Sauf que ce n'est pas sur un tableau que j'itère, c'est "sur" le PDOStatement (tant que le résultat de la requête comporte une ligne). Sachant d'ailleurs qu'une instance PDOStatement est itérable, il est parfaitement possible d'écrire foreach ($req as $row) à while($row = $req->fetch()).
A mon tour de te citer les lacunes de ton code :
XSS faute de htmlspecialchars
tu cherches à faire du dynamique mais les noms des colonnes sont hardcodées
et ça ne m'explique pas les foreach imbriqués où tu itères sur 2 tableaux d'un élément ?!?
EDIT : les 2 derniers points étaient par rapport au PO
J'ajouterais que ton exemple est au mieux mal choisi :
3 fois la même requête ?
au lieu tout mettre en mémoire via des tableaux (ce qui peut être gênant s'il y a vraiment beaucoup de lignes), rien n'empêche d'utiliser UNION
> deux boucles pour les td
J'aurais dit 1 (cf ma remarque au sujet de l'imbrication des foreach)
> Il vaut mieux séparer les deux.
Là-dessus d'accord, enfin, je me base sur le code de départ. Toujours est-il qu'un PDOStatement étant itérable il n'est pas forcément utile de tout rapatrier en mémoire.
EDIT : oups, autant pour moi, j'ai cru répondre au PO
> <?php strip_tags(
L'instruction ne fait/sert à rien, autant virer le if par une négation
> <?= ( empty($value) ) ? "NULL" : $value; ?>
Attention à empty (0 est une valeur vide)
Je ne suis vraiment pas fan de ta technique de tableau de tableaux (de tableaux) : il faut vraiment avoir envie d'afficher les tableaux à la suite et avec la même logique. On est loin de la généricité d'une vue.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Activer les erreurs PDO / (julp) htmlspecialchars / FAQ PHP / Pas d'aide par MP
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli