[PDO] Affichage par catégorie avec PDO

ViPHP
ViPHP | 5462 Messages

07 juil. 2010, 22:23

PDO offre une option intéressante dans son fetchMode : PDO::FETCH_GROUP qui permet de grouper des entrées par catégorie.

exemple :
+----+-----------+----------+-------+
| id | firstname | lastname | city  |
+----+-----------+----------+-------+
|  1 | Jean      | Machin   | Paris |
|  2 | Jean      | Truc     | Nice  |
|  3 | Paul      | Bla      | Nice  |
+----+-----------+----------+-------+
on a envie de trier les utilisateurs par ville pour avoir une sortie type :

Code : Tout sélectionner

Paris Jean Machin Nice Jean Truc Paul Bla
plusieurs solutions :
  • Faire une requête DISTINCT sur les villes, et a chaque tour de boucle allé chercher les personnes qui correspondes
  • Créer un array temporaire et a chaque tour de boucle ajouter la personne ($tmp[$user['city']][] = $user) , et reboucler ensuite pour créer son tableau
  • A chaque tour de boucle vérifier via un buffer si la ville a été mise et afficher les personnes, sinon afficher ville
la solution PDO :

Grâce au fetchAll et son option PDO::FETCH_GROUP, on a en sortie directement un array formateé, avec en clé la catégorie et en valeur les entrées correspondantes
(par contre attention contraiement a PDO::FETCH_COLUMN, on ne choisie pas qui est la catégorie, ca sera uniquement la première colonne)

exemple de code :
try
{
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'root');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
catch (Exception $e)
{
    exit($e->getMessage());
}
	
$query = $pdo->query("SELECT u.city, u.id, u.firstname, u.lastname FROM test_user u");
	
if($query)
{
    $result = $query->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_GROUP);
    print_r($result);
}
en sortie

Code : Tout sélectionner

Array ( [Paris] => Array ( [0] => Array ( [id] => 1 [firstname] => Jean [lastname] => Machin ) ) [Nice] => Array ( [0] => Array ( [id] => 2 [firstname] => Jean [lastname] => Truc ) [1] => Array ( [id] => 3 [firstname] => Paul [lastname] => Bla ) ) )
tout simplement :wink:

Si on veux que la catégorie sois un autre champs il suffis de le mettre en premier (le prénom par exemple)
SELECT u.firstname, u.id, u.lastname, u.city FROM test_user u

Code : Tout sélectionner

Array ( [Jean] => Array ( [0] => Array ( [id] => 1 [lastname] => Machin [city] => Paris ) [1] => Array ( [id] => 2 [lastname] => Truc [city] => Nice ) ) [Paul] => Array ( [0] => Array ( [id] => 3 [lastname] => Bla [city] => Nice ) ) )
et on peux bien sur doubler les valeurs pour avoir des entrées complètes, ce qui sera d'ailleurs plus simple, au niveau portabilité et pour différentes sorties
SELECT u.city, u.id, u.firstname, u.lastname, u.city FROM test_user u
-- ou version raccourcis
SELECT u.city, u.* FROM test_user u

Code : Tout sélectionner

Array ( [Paris] => Array ( [0] => Array ( [id] => 1 [firstname] => Jean [lastname] => Machin [city] => Paris ) ) [Nice] => Array ( [0] => Array ( [id] => 2 [firstname] => Jean [lastname] => Truc [city] => Nice ) [1] => Array ( [id] => 3 [firstname] => Paul [lastname] => Bla [city] => Nice ) ) )
Modifié en dernier par stealth35 le 20 juil. 2011, 14:31, modifié 3 fois.

Eléphant du PHP | 185 Messages

09 juil. 2010, 09:40

Moi je dis : merci !

Ça c'est une astuce qu'elle est bonne !

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13235 Messages

09 juil. 2010, 10:19

Effectivement, très bonne contribution. :pouce:

Je pense que ça fait parti des petites astuces qui ne sont pas très connues, mais qui méritent de l'être ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 209 Messages

15 juil. 2010, 11:41

Salut à tous,

Tout d'abord, merci pour cette contribution, c'est une astuce très utile !
Par contre, j'ai essayé de l'utiliser sur un compte free.fr, et là, surprise, PDO n'est pas installé...
J'ai donc codé cette petite fonction qui fait la même chose :

function fetchAll($query, $champ)
{

	$tt = '';
	$result = array();

	while($r = mysql_fetch_assoc($query))
	{

		if($tt != $r[$champ])
		{
			$tt = $r[$champ];
		}

		$result[$tt][] = $r;
	}
}
La variable $champ détermine le champ que l'on veut retrouver en indice du tableau.

ViPHP
ViPHP | 5462 Messages

15 juil. 2010, 11:45

Par contre, j'ai essayé de l'utiliser sur un compte free.fr, et là, surprise, PDO n'est pas installé...
sous free, PDO est installer mais uniquement avec sqlite2 et sqlite :wink:

Eléphant du PHP | 209 Messages

15 juil. 2010, 23:13

Oui, c'est vrai, j'ai oublié de préciser que j'utilise MySQL.

Eléphant du PHP | 171 Messages

20 juil. 2011, 13:57

Merci pour l'astuce ! Je connaissais pas et j'utilisais toujours les autres solutions et le faire direct avec PDO c'est niquel ;)
Le bon jugement s'apprend par l'expérience qui s'acquiert en partie par le mauvais jugement.