3.2 La classe Tableau 143 tableau E, assez éloigné des autres, sera ignoré. Voici, pour un tableau avec deux dimensions d 1 et d 2 , la représentation adoptée. CSG e[d 2 , c 1 2 ] e[d 2 , c 2 2 ] e[d 3 , c q 2 ] e[d 1 , c 1 1 ] M[c 1 1 , c 1 2 ] M[c 1 1 , c 2 2 ] M[c 1 1 , c q 2 ] e[d 1 , c 2 1 ] M[c 2 1 , c 1 2 ] M[c 2 1 , c 2 2 ] M[c 2 1 , c q 2 ] e[d 1 , c p 1 ] M[c p 1 , c 1 2 ] M[c p 1 , c 2 2 ] M[c p 1 , c q 2 ] Tableau 3.7 — Les méthodes publiques de la classe tableau Méthode Description Tableau (tabAttrs ) Constructeur de tableaux en fonction d’une dimen- sion et d’une liste de paramètres de présentation. ajoutValeur (ligne, colonne, valeur ) Définit la valeur du tableau dans une cellule donnée par les paramètres ligne et colonne. ajoutEntete (dimension, cle, texte ) Définit l’en-tête pour la dimension dimension et la clé cle. TableauHTML () Produit la représentation HTML du tableau. ajoutAttributsTable (tabAttrs ) Ajouts de paramètres de présentation pour la balise <table>. setCouleurPaire (couleur ) Couleur de fond pour les lignes paires. setCouleurImpaire (couleur ) Couleur de fond pour les lignes impaires. setAfficheEntete (dimension, couleur ) Indique si l’on souhaite ou non afficher l’en-tête pour la dimension. setCoinSuperieurGauche (texte ) Texte à placer dans le coin supérieur gauche. Les éléments apparaissant dans cette présentation sont : • Le libellé du coin supérieur gauche CSG (dans le tableau C par exemple c’est « Box office ») ; • les clés de la dimension 1, notées c i 1 , pour chaque ligne i,avec1 i p (dans le tableau B ce sont les titres de films ; dans le tableau C les villes) ; • les clés de la dimension 2, notées c j 2 , pour chaque ligne j,avec1 j q (dans notre exemple il s’agit de ’Semaine’ suivi du numéro de la semaine) ; • les en-têtes de la dimension d k ,notése[d k , c i k ],aveck = 1ouk = 2; • enfin M[i, j] désigne la valeur de la mesure pour la position (i, j) du tableau. Une fois cet effort de modélisation effectué, tout le reste devient facile. Les informations précédentes doivent pouvoir être manipulées par l’intermédiaire de l’interface de la classe Tableau et donc être stockées comme propriétés des objets de la classe Tableau. Par ailleurs, elles doivent être accessibles en entrée ou en sortie par l’intermédiaire d’un ensemble de méthodes publiques. Ce modèle de tableau capture les exemples A et B. En l’étendant à trois dimen- sions, on obtient également les présentations C et D. En revanche il ne convient pas 144 Chapitre 3. Programmation objet au tableau E : il faut savoir renoncer aux cas qui rendent beaucoup plus complexes les manipulations sans que cela soit justifié par le gain en puissance. Dans ce qui suit, nous donnons des exemples d’utilisation, ainsi que l’implanta- tion de la classe, en nous limitant au cas à deux dimensions. La gestion d’un nombre de dimensions quelconque est partiellement réalisée dans le code fourni sur le site, et partiellement laissée au lecteur (le polycopié d’exercices fournit des suggestions complémentaires). 3.2.2 Utilisation La table 3.7 donne la liste des méthodes publiques de la classe Tableau. On trouve bien entendu le constructeur de la classe, qui prend en paramètres la dimension du tableau et des attributs HTML à placer dans la balise <table>. Les trois méthodes suivantes sont les plus importantes. Elles définissent respectivement l’ajout d’une valeur dans une cellule (le tableau M des mesures), la description des en-têtes (le tableau e) et enfin la sortie de la chaîne de caractères contenant la représentation HTML du tableau. Les autres méthodes publiques sont moins essentielles. Elles permettent de régler l’apparence du tableau en affectant certaines valeurs à des paramètres internes à la classe utilisés ensuite au moment de la génération de la chaîne HTML. Voyons maintenant comment on utilise cette classe dans une petite application de test qui extrait des données de MySQL et les affiche sous forme de tableau HTML. Le script SQL suivant permet de créer la table BoxOffice (les exemples contiennent un autre script, InsBoxOffice.sql, pour insérer un échantillon de données dans cette table). Exemple 3.7 exemples/BoxOffice.sql : Création de la table BoxOffice. # Création d ’une table pour box office simplifié CREATE TABLE BoxOffice (titre VARCHAR(60) NOT NULL, semaine INTEGER NOT NULL, ville VARCHAR(60) NOT NULL, n b _e n tr e e s INTEGER NOT NULL, PRIMARY KEY (titre , semaine , ville) ); Le script ApplClasseTableau.php, ci-dessous, instancie deux objets de la classe Tableau, correspondant aux présentations A et B données précédemment. Ces deux objets sont alimentés à partir des lignes issues d’une même requête, ce qui montre concrètement comment on peut facilement choisir une présentation particulière en partant des mêmes données. Notez qu’il n’y a pratiquement plus une seule balise HTML apparaissant dans ce script. La figure 3.3 donne le résultat. 3.2 La classe Tableau 145 Exemple 3.8 exemples/ApplClasseTableau.php : Application de la classe Tableau. <?xml version=" 1.0 " encoding="iso −8959−1"?> <!DOCTYPE htm l PUBLIC " −/ /W3C / / DTD XHTML 1 . 0 S t r i c t / / EN " "http ://www.w3. org/TR/xhtml1/DTD/xhtml1− strict .dtd"> <html xmlns="http ://www.w3. org/1999/xhtml" xml:lang="fr " > <head> <title >La classe tableau </title > < link rel=’ stylesheet ’ href="films. css" type="text/css"/> </head> <body> <?php require_once ("Connect.php"); require_once ("BDMySQL.php"); require_once ("Tableau.php") ; try { // Connexion à la base de données $bd = new BDMySQL (NOM, PASSE, BASE, SERVEUR) ; // Création du premier tableau $tableauA = new Tableau(2 , array("border"=>2)) ; $tableauA−>setAfficheEntete(1, FALSE); // Création du second tableau $tableauB = new Tableau(2, array("border"=>2)) ; $tableauB−>setCoinSuperieurGauche("Box office"); $tableauB−>setCouleurImpaire(" silver "); $i=0; // Recherche des films parisiens $resultat = $bd−>execR equete ( "SELECT ∗ FROM BoxOffice WHERE ville=’Paris ’"); while ($bo = $bd−>objetSuivant ($resultat)) { // Premier tableau : présentation standard , en colonnes $i ++; $tableauA−>ajoutValeur($i , "Film" , $bo−>titre); $tableauA−>ajoutValeur($i , "Ville" , $bo−>ville); $tableauA−>ajoutValeur($i , "Semaine" , $bo−>semaine) ; $tableauA−>ajoutValeur($i , "Nb entrées" , $bo−>nb_entrees); // Second tableau : présentation par titre et par semaine $tableauB−>ajoutEntete(2, $bo−>semaine , "Semaine " . $bo−> semaine) ; $tableauB−>ajoutValeur($bo−>t itre , $bo−>semaine , $bo−> nb_entrees); } // Affichage des tableaux echo $tableauA−>tableauHTML() . "<br/>\n" ; 146 Chapitre 3. Programmation objet echo $tableauB−>tableauHTML() . "<br/>\n" ; } catch (Exception $exc) { // Une erreur est survenue echo "<b>Erreur rencontrée:</b> " . $exc−>getMessage () . "\n" ; } ?> </body> </html> Figure 3.3 — Affichage des deux tableaux. Bien entendu on utilise un objet de la classe BDMySQL pour se connecter, effectuer une requête et parcourir le résultat. Ce qui nous intéresse ici c’est la production des tableaux. Le premier, tableauA, est instancié comme suit : $tableauA = new Tableau(2, array("border"=>2)) ; $tableauA−>setAfficheEntete(1, FALSE); On indique donc qu’il s’agit d’un tableau à deux dimensions, avec une bordure de 2 pixels. On peut noter la pratique consistant à passer un nombre variable de paramètres (ici des attributs HTML) sous la forme d’un tableau PHP. La seconde instruction supprime l’affichage des en-têtes de la dimension 1. Ensuite, à chaque fois que la boucle sur le résultat de la requête renvoie un objet bo, on insère des valeurs avec la méthode ajoutValeur(). Rappelons que cette fonction définit la valeur de M[c 1 , c 2 ] où c 1 (respectivement c 2 ) est la clé désignant la ligne (respectivement la colonne) de la cellule. 3.2 La classe Tableau 147 $i ++; $tableauA−>ajoutValeur($i , "Film" , $bo−>titre ); $tableauA−>ajoutValeur($i , "Ville" , $bo−>ville); $tableauA−>ajoutValeur($i , "Semaine" , $bo−>semaine) ; $tableauA−>ajoutValeur($i , "Nb entrées" , $bo−>nb_entrees) ; Ici la clé de la dimension 1 (les lignes) est basée sur un compteur incrémenté à chaque passage dans la boucle, et la clé de la dimension 2 (les colonnes) est un texte qui servira également d’en-tête (voir figure 3.3). Pour le second tableau, tableauB, on applique les mêmes principes. L’instancia- tion est identique. On appelle deux méthodes qui fixent le libellé du coin supérieur gauche, et une couleur de fond pour les lignes impaires. $tableauB−>setCoinSuperieurGauche("Box office ") ; $tableauB−>setCouleurImpaire(" silver "); Puis, à chaque passage dans la boucle, on insère une valeur de la mesure nbEntr´ees indexée par le titre du film (dimension 1, les lignes) et par la semaine (dimension 2, les colonnes). De plus, au lieu de garder l’en-tête par défaut pour les colonnes (le numéro de la semaine), on le définit avec la méthode ajoutEntete() comme étant la concaténation de la chaîne "Semaine " et du numéro de semaine. $tableauB−>ajoutEntete(2, $bo−>semaine , "Semaine " . $bo−>semaine); $tableauB−>ajoutValeur($bo−>titre , $bo−>semaine , $bo−>nbEntrees) ; Il n’y a rien de plus à faire. L’appel de la méthode tableauHTML() renvoie une chaîne qui peut être placée dans un document HTML. Bien entendu on pourrait améliorer la présentation, par exemple en cadrant à droite les colonnes contenant des nombres. C’est possible – et facile- - en ajoutant des méthodes appropriées à la classe Tableau. Ce type d’extension est très utile à réaliser pour bien comprendre comment fonctionne une classe. Cet exemple montre comment la programmation objet permet de s’affranchir de détails de bas niveau comme, ici, les balises HTML à utiliser en ouverture et en fermeture ou l’ordre de création des cellules. On se contente de déclarer le contenu du tableau et l’objet se charge de fournir une chaîne de caractères contenant sa description HTML. Cette chaîne peut alors être utilisée par l’application comme bon lui semble. On pourrait par exemple la placer dans une cellule d’un autre tableau pour obtenir très facilement des imbrications. Ce qui compte, pour bien utiliser la classe, c’est d’une part de comprendre la modélisation (et donc ce qu’est conceptuellement un objet tableau), et d’autre part de connaître les modes de contrôle et d’interaction avec l’objet. . comment on utilise cette classe dans une petite application de test qui extrait des données de MySQL et les affiche sous forme de tableau HTML. Le script SQL suivant permet de créer la table BoxOffice. script ApplClasseTableau.php, ci-dessous, instancie deux objets de la classe Tableau, correspondant aux présentations A et B données précédemment. Ces deux objets sont alimentés à partir des lignes. classe. Cet exemple montre comment la programmation objet permet de s’affranchir de détails de bas niveau comme, ici, les balises HTML à utiliser en ouverture et en fermeture ou l’ordre de création des