Ok, je voulais être sûr.
En fait, je m'étais fait un truc à des fins de débogage précisément pour ça. Je n'utilise pas de do/while du tout, je me suis construit la petite classe suivante :
<?php
/**
* Construction d'un tableau HTML dynamique pour un jeu de
* résultats issus d'une requête SQL, quel que soit le nombre de colonnes et/ou de
* lignes retournées.
*
* Le tableau comportera en en-tête le nom des colonnes, même si la requête est
* du type « SELECT * FROM ... » et en pied de tableau le nombre total de lignes
* affichées.
*
* Utilisation :
* Il faut dans un premier temps récupérer le jeu de résultats dans un tableau (voir les
* commentaires du constructeur.)
* L'exemple suivant est simplifié et part de l'utilisation d'une classe qui va exécuter la
* requête SQL et retourner un tableau indexé :
* <code>
* $oDb = new mydb();
* $sql = "SELECT * FROM matable WHERE condition = 1";
* $oDb->execute($sql);
* $aDatas = $oDb->fetchAssoc();
*
* </code>
* On crée ensuite une instance en lui passant ce tableau en paramètre.
* <code>
* $oTable = new db_html_table($aDateFct);
* </code>
* Si l'instance existait déjà, on met à jour les informations avec le nouveau je de résultats à
* afficher avec la méthode setNewTable().
* <code>
* $oTable->setNewTable($aDatas);
* </code>
* Enfin, on récupère le tableau HTML avec la méthode getTableau.
* <code>
* echo($oTable->getTableau());
* </code>
*/
class db_html_table
{
/**
* Tableau de données à 3 dimensions de résultat de requête SQL.
*
* @var Array
*/
private $_aInfos = array();
/**
* Table HTML d'affichage du contenu du tableau.
*
* @var String
*/
private $_sTableau = '';
/**
* Définition de l'instance.
*
* Le tableau de données attendues sera de la forme suivante :
* tableau => array(
* 0 => array(
* 'nom_colonne_1' => 'valeur_1',
* 'nom_colonne_2' => 'valeur_2',
* 'nom_colonne_...' => 'valeur_...',
* 'nom_colonne_n' => 'valeur_n',
* ),
* 1 => array(
* 'nom_colonne_1' => 'valeur_1',
* 'nom_colonne_2' => 'valeur_2',
* 'nom_colonne_...' => 'valeur_...',
* 'nom_colonne_n' => 'valeur_n',
* ),
* etc...
* )
*
* @param Array $aInfos
*/
public function __construct($aInfos = null)
{
$this->_aInfos = (!is_null($aInfos)) ? $aInfos : array();
}
/**
* Remplacement des données par un nouveau tableau à 3 dimensions.
*
* Permet l'utilisation de l'instance en cours pour un autre jeu de résultat à afficher
*
* @param Array $aInfos
*/
public function setNewTable($aInfos)
{
$this->_aInfos = $aInfos;
$this->_sTableau = '';
}
/**
* Construction dynamique d'une table HTML pour afficher
* le contenu du tableau.
*
* @param Array $aInfos Optionnel, si absent, le jeu de résultat passé au constructeur sera utilisé.
* @param String $sTable Optionnel, nom de la table ou de la vue qui servira de titre du tableau.
* @return String
*/
public function getTableau($aInfos = null, $sTable = null)
{
if(is_null($aInfos))
{
$aInfos = $this->_aInfos;
}
$nl = count($aInfos);
$label = (isset($sTable)) ? 'Contenu de la table '. $sTable .' : ' : null;
if($nl == 0):
/* Tableau de données vide, donc on affiche simplement un message */
$this->_sTableau = <<<CODE
<p class="erreur">{$label}Pas de données disponibles pour ces critères.</p>
<hr />
CODE;
else:
/* Il y a des données, on va identifier les noms des colonnes et leur nombre */
$l1 = $aInfos[0];
$aIndexes = array();
/* On construit le header avec les noms des colonnes et le footer avec le nombre total de lignes */
$this->_sTableau = <<<CODE
<table summary="{$label}">
<caption>{$label}</caption>
<thead>
<tr>
CODE;
foreach ($l1 as $index => $val):
$aIndexes[] = $index;
$this->_sTableau .= <<<CODE
<th>{$index}</th>
CODE;
endforeach;
$nc = count($aIndexes);
$s = ($nl > 1) ? 's' : null;
$this->_sTableau .= <<<CODE
</tr>
</thead>
<tfoot>
<tr>
<td colspan="{$nc}">{$nl} ligne{$s}</td>
</tr>
</tfoot>
<tbody>
CODE;
/* On construit maintenant les lignes de données */
foreach($aInfos as $i => $ligne):
$this->_sTableau .= <<<CODE
<tr>
CODE;
foreach ($aIndexes as $idcol):
$align = (is_numeric($ligne[$idcol])) ? ' style="text-align: right;"' : null;
$this->_sTableau .= <<<CODE
<td{$align}>{$ligne[$idcol]}</td>
CODE;
endforeach;
$this->_sTableau .= <<<CODE
</tr>
CODE;
endforeach;
$this->_sTableau .= <<<CODE
</tbody>
CODE;
$this->_sTableau .= <<<CODE
</table>
<hr />
CODE;
endif;
return($this->_sTableau);
}
}
Ensuite, ben c'est pas très dur à utiliser, dans ton cas, si je reprends un tout petit bout de ton premier code, ça devrait ressembler à quelque chose dans ce style là :
<?php
$stmt = $pdo->query('SELECT * FROM test');
$stmt->setFetchMode(PDO::FETCH_ASSOC);
/* Ici est le bout important : on alimente le tableau des données à afficher */
$aDatas = array();
while(false != ($row = $stmt->fetch()))
{
$aDatas[] = $row;
}
/* Inclusion de la classe et création de l'instance : */
include_once($classetableau);
$oTable = new db_html_table();
/* Affichage : */
echo($oTable->getTableau($aDatas, 'Test'));
C'est tout, je te laisse observer ce que ça donne, que ton tableau ait 1 ou 25 colonnes, et de 1 à 5 000 000 de lignes, ça fera l'affaire et s'il n'y a pas de résultat du tout, ben ce sera traité aussi.
J'ai largement commenté le code de la classe, je te laisse l'adapter si nécessaire
