Regroupement de données (SQL ou tableau) en PHP

5 08 2009

Je vous propose une fonction PHP permettant de regrouper (ou hiérarchiser) des données fournies sous formes de lignes (venant d’un tableau ou d’une requête SQL).

Illustration du problème

Imaginez que vous ayez des données dans un tableau :

Cinéma Film Horaire
Pathé Docks 76 Le hérisson 22h15
Gaumont Multiplex Là-haut 22h20
Pathé Docks 76 Là-haut 22h15
Gaumont Multiplex Le hérisson 22h20
Gaumont Multiplex L’âge de glace 3 − Le temps des dinosaures 20h00
Gaumont Multiplex L’âge de glace 3 − Le temps des dinosaures 22h20
Pathé Docks 76 L’âge de glace 3 − Le temps des dinosaures 19h15
Pathé Docks 76 L’âge de glace 3 − Le temps des dinosaures 20h15

Il y a plusieurs façons de regrouper ces données :

  • par cinéma / film / horaire,
  • par horaire / film / cinéma,
  • par cinéma / horaire / film,
  • par film / horaire / cinéma,
  • etc.

Pour ceux qui utilisent les tableaux dynamiques d’Excel, ce concept devrait être familier.

Ces informations peuvent être stockées dans un tableau PHP ou dans des tables MySQL, la structure la plus simple restant d’enregistrer chaque séance dans une ligne.

Les fonctions

Les fonctions maketree_array et maketree_sql vont vous permettre de produire une arborescence à partir de telles données.

L’arborescence sera produite sous la forme de tableaux associatifs imbriqués :

$cinemas=array(
  'Pathé Docks 76'=>array(
    'Le hérisson'=>array(array('horaire'=>'22h15')),
    'Là-haut'    =>array(array('horaire'=>'22h15')),
    'L’âge de glace 3 − Le temps des dinosaures'=>array(
      array('horaire'=>'19h15'),
      array('horaire'=>'20h15')
    )
  ),
  'Gaumont Multiplex'=>array(
    'Là-haut'    =>array(array('horaire'=>'22h20')),
    'Le hérisson'=>array(array('horaire'=>'22h20')),
    'L’âge de glace 3 − Le temps des dinosaures'=>array(
      array('horaire'=>'20h00'),
      array('horaire'=>'22h20')
    )
  )
);

Ce tableau serait produit pour un regroupement cinéma / film / horaire.

Les feuilles les plus basses se présentent également sous la forme de tableaux associatifs car les fonctions permettent de conserver les niveaux non regroupés. On aurait pu avoir des colonnes supplémentaires (avant-première, version originale sous-titrée, etc.), elles se seraient retrouvées dans le tableau associatif.

Fonction maketree_array

Voici le code PHP de la fonction maketree_array qui prend en entrée un tableau ($items) :

function maketree_array($items,$keys) {
  $tree =array();
  $dkeys=array();

  foreach($keys as $key) $dkeys[$key]='';

  switch(count($keys)) {
    case 1:
      foreach($items as $item) {
        $tree[$item[$keys[0]]][]=array_diff_key($item,$dkeys);
      }
      break;

    case 2:
      foreach($items as $item) {
        $tree[$item[$keys[0]]][$item[$keys[1]]][]=array_diff_key($item,$dkeys);
      }
      break;

    case 3:
      foreach($items as $item) {
        $tree[$item[$keys[0]]][$item[$keys[1]]][$item[$keys[2]]][]=array_diff_key($item,$dkeys);
      }
      break;
  }

  return $tree;
}

Elle s’utilise de la façon suivante :

$seances=array(
  array('cinema'=>'Pathé Docks 76'   ,'film'=>'Le hérisson'                               ,'horaire'=>'22h15'),
  array('cinema'=>'Gaumont Multiplex','film'=>'Là-haut'                                   ,'horaire'=>'22h20'),
  array('cinema'=>'Pathé Docks 76'   ,'film'=>'Là-haut'                                   ,'horaire'=>'22h15'),
  array('cinema'=>'Gaumont Multiplex','film'=>'Le hérisson'                               ,'horaire'=>'22h20'),
  array('cinema'=>'Gaumont Multiplex','film'=>'L’âge de glace 3 − Le temps des dinosaures','horaire'=>'20h00'),
  array('cinema'=>'Gaumont Multiplex','film'=>'L’âge de glace 3 − Le temps des dinosaures','horaire'=>'22h20'),
  array('cinema'=>'Pathé Docks 76'   ,'film'=>'L’âge de glace 3 − Le temps des dinosaures','horaire'=>'19h15'),
  array('cinema'=>'Pathé Docks 76'   ,'film'=>'L’âge de glace 3 − Le temps des dinosaures','horaire'=>'20h15')
);

$cinemas=maketree_array($seances,array('cinema','film'));

var_dump($cinemas);

Cet exemple va produire le tableau présenté au début du chapître “Les fonctions”.

Les colonnes non précisées dans la liste des clés sont toutes conservées dans les feuilles finales de l’arbre ainsi créé.

La fonction est limitée à 3 niveaux. D’une part, cela couvre un maximum de besoins. D’autre part, il est aisé de rajouter autant de niveau que voulus.

Fonction maketree_sql

La fonction maketree_sql fonctionne uniquement sous Drupal (appel à la fonction db_fetch_array()).

Son principe de fonctionnement est le même que pour maketree_array sauf qu’il faut donner en entrée le retour de la fonction db_query et non pas un tableau.

Voici le code source de la fonction maketree_sql :

function maketree_sql($result,$keys) {
  $tree =array();
  $dkeys=array();

  foreach($keys as $key) $dkeys[$key]='';

  switch(count($keys)) {
    case 1:
      while($item=db_fetch_array($result)) {
        $tree[$item[$keys[0]]][]=array_diff_key($item,$dkeys);
      }
      break;

    case 2:
      while($item=db_fetch_array($result)) {
        $tree[$item[$keys[0]]][$item[$keys[1]]][]=array_diff_key($item,$dkeys);
      }
      break;

    case 3:
      while($item=db_fetch_array($result)) {
        $tree[$item[$keys[0]]][$item[$keys[1]]][$item[$keys[2]]][]=array_diff_key($item,$dkeys);
      }
      break;
  }

  return $tree;
}

Et après…

Il est possible d’utiliser plusieurs requêtes SQL pour arriver au même résultat. Il est préférable toutefois de limiter le nombre de requêtes.

Il est également possible d’utiliser une seul requête SQL et d’insérer de multiples tests dans les boucles imbriquées pour détecter les changements de valeurs. Fastidieux si vous voulez mon avis.

Pour pouvoir utiliser les tableaux ou arborescences générés par ces fonctions, on peut utiliser un code comme celui-ci :

foreach($cinemas as $cinema=>$films) {
  // $cinema contient le nom du cinéma
  foreach($films as $film=>$seances) {
    // $film contient le nom du film
    foreach($seances as $seance) {
      // utiliser $seance['horaire']
    }
  }
}

Voilà ! À vous d’inventer le reste !😉


Actions

Information

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s




%d blogueurs aiment cette page :