Bonjour à tous,

Après une mise de coté très longue de php, je dois m'y remettre et j'en ai repris l'étude avec un bouquin : Pratique de MySQL et PHP de Philippe Rigaux.

Dans le bouquin, une classe Tableau est développée, mais incomplète. Il faut y rajouter des tests et implémenter certaines méthodes.

Mon problème est que je ne parviens pas à tester le nombre de dimensions nécessaire à la création de l'instance tableau. Je ne comprends pas pourquoi ça ne fonctionne pas.

Voici le code complet de la classe Tableau:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
<?php
// Classe pour la production de tableaux HTML

class Tableau
{
	// ----   Partie privée : les constantes et les variables
	private $nb_dimensions;

	// Tableau des valeurs à afficher
	private $tableau_valeurs;

	// Tableaux des entêtes
	private $entetes, $options_lig, $options_col, $options_entete;

	// Options de présentation pour la table. A compléter.
	private $options_tables, $couleur_paire, $couleur_impaire, $csg, $affiche_entete, $repetition_ligne = array(), $option_dim = array(), $legende;

	// Constante pour remplir les cellules vides
	const VAL_DEFAUT = "&nbsp;";

	// Constructeur
	function __construct($nb_dimensions = 2, $tab_attrs = array())
	{
		// Initialisation des variables privées
		$this->tableau_valeurs = array();
		$this->options_tables = $this->couleur_paire = $this->couleur_impaire = $this->legende = $this->options_entete = "";

		// Initialisation de la dimension. Quelques tests s'imposent...
		// Mon test qui ne fonctionne pas (l'exception n'est pas lancée...) :
		if ($nb_dimensions < 2)
			throw new Exception("un message d'erreur");
		
		$this->nb_dimensions = $nb_dimensions;

		// Initialisation des tableaux d'entêtes pour chaque dimension
		for ($dim = 1; $dim <= $this->nb_dimensions; $dim++)
		{
			$this->entetes[$dim] = array();
			$this->affiche_entete[$dim] = TRUE;
		}
		
		// Attributs de la balise <TABLE>
		$this->ajoutAttributsTable($tab_attrs);
	}
  	
	// Méthode ajoutant des attributs HTML pris dans un tableau
	function ajoutAttributsTable($tab_attrs = array())
	{
		foreach ($tab_attrs as $nom_attr => $val_attr)
			$this->options_tables .= " $nom_attr='$val_attr' ";
	}

	// Méthodes définissant les couleurs paire et impaire
	function setLegende($text)  
	{
		$this->legende = $text;
	}
	
	function setCouleurPaire($couleur)  
	{
		$this->couleur_paire = $couleur;
	}
	
	function setCouleurImpaire($couleur)  
	{
		$this->couleur_impaire = $couleur;
	}

	// Méthode permettant d'afficher ou non un entête
	function setAfficheEntete($dim, $bool)  
	{
		$this->affiche_entete[$dim] = $bool;
	}

	// Méthode permettant de répéter n fois l'affichage d'une ligne
	function setRepetitionLigne($dim, $cle, $nb_repetitions)  
	{
		$this->repetition_ligne[$dim][$cle] = $nb_repetitions;
	}

	// Méthode indiquant des options pour une ligne ou une colonne
	function setOption ($dim, $cle, $options = array())  
	{
		foreach ($options as $option => $valeur)
			$this->options[$dim][$cle][$option] = $valeur;
	}

	// Méthode permettant d'afficher le coin supérieur gauche
	function setCoinSuperieurGauche($texte) 
	{
		$this->csg = $texte;
	}

	// Méthode définissant des attributs pour les entêtes, lignes,
	// colonnes: à faire!!
	function ajoutAttributsEntete($options) 
	{
		foreach ($options as $cle => $val_attr)
			$this->options_entete .= " $cle='$val_attr' ";
	}
	
	function ajoutAttributsLigne($cle_ligne, $options) 
	{
		$this->setOption(1, $cle_ligne, $options);
	}
	
	function ajoutAttributsColonne($cle_colonne, $options) 
	{
		$this->setOption(2, $cle_colonne, $options);
	}

	// TABLEAU A DEUX DIMENSIONS: ajout d'une valeur dans une cellule
	function ajoutValeur($cle_ligne, $cle_colonne, $valeur)
	{
		// Maintenance des entêtes
		if (!array_key_exists($cle_ligne, $this->entetes[1]))
			$this->entetes[1][$cle_ligne] = $cle_ligne;

		if (!array_key_exists($cle_colonne, $this->entetes[2]))
			$this->entetes[2][$cle_colonne] = $cle_colonne;

		// Stockage de la valeur
		$this->tableau_valeurs[$cle_ligne][$cle_colonne] = $valeur;
	}

	// TABLEAU A N DIMENSIONS: ajout d'une valeur dans une cellule
	// Le premier paramètre est un tableau qui contient les clés.
	// Par exemple: array(1=>"Cle1", 2=>"Cle2", 3=>"Cle3")
	function ajoutValeurDimN($position, $valeur)
	{
		// On construit les coordonnées au fur et à mesure
		$coord  = "";

		for ($dim = 1; $dim <= $this->nb_dimensions; $dim++)
		{
			$cle = $position[$dim];
			
			// Par défaut, les entêtes valent la clé (si elles n'existent pas)
			if (!array_key_exists($cle, $this->entetes[$dim]))
				$this->entetes[$dim][$cle] = $cle;

			$coord .= "['$cle']";
		}
		
		// On construit la commande et on l'exécute
		eval ("\$this->tableau_valeurs$coord='$valeur';");
	}

	// Méthode définissant un entête, avec texte
	function ajoutEntete($dimension, $cle, $texte)
	{
		// Stockage de la chaîne servant d'entête
		$this->entetes[$dimension][$cle] = $texte;
	}

	// Production du tableau HTML: ne marche qu'en dimension 2!!
	// A FAIRE: généraliser cette fonction pour obtenir les
	// tableaux A, B, C, D présentés dans le livre
	function tableauHTML()
	{
		$chaine = $ligne = "";
		
		/* Pour afficher les tableaux d'entêtes.
		print_r ($this->entetes[1]);
		print_r ($this->entetes[2]); */

		// Affiche-t'on le coin supérieur gauche?
		if ($this->affiche_entete[1]) 
			$ligne = "<th>$this->csg</th>";
			
		if (!empty($this->legende))
		{
			$nb_cols = count($this->entetes[2]);
			$chaine = "<tr class='header'>\n<th colspan=$nb_cols>$this->legende" . "</th>\n</tr>\n";
		}

		// Création des en-têtes de colonnes (dimension 2)
		if ($this->affiche_entete[2])
		{
			foreach ($this->entetes[2] as $cle => $texte)
				$ligne .= "<th $this->options_entete>$texte</th>\n";

			// Ligne des en-têtes.
			$chaine = "<tr class='header'>$ligne</tr>\n";
		}

		$i = 0;
		
		// Boucles imbriquées sur les deux tableaux de clés
		foreach ($this->entetes[1] as $cle_lig => $enteteLig) // Lignes
		{
			if ($this->affiche_entete[1])
				$ligne = "<th>$enteteLig</th>\n";
			else
				$ligne = "";
			
			$options_col = "";
			$i++;

			foreach ($this->entetes[2] as $cle_col => $enteteCol) // Colonnes
			{
				// On prend la valeur si elle existe, sinon le défaut
				if (isSet($this->tableau_valeurs[$cle_lig][$cle_col]))
					$valeur = $this->tableau_valeurs[$cle_lig][$cle_col];
				else
					$valeur = self::VAL_DEFAUT;
				
				
				// Doit-on appliquer des options aux colonnes ?
				if (isSet($this->options[2][$cle_col]))
				{
					foreach ($this->options[2][$cle_col] as $option => $val)
						$options_col .= " $option='$val' ";
				}

				// On place la valeur dans une cellule
				$ligne .= "<td $options_col>$valeur</td>\n";
				$options_col = "";
			}
			
			// Eventuellement on tient compte de la couleur
			if ($i % 2 == 0)
			{
				$options_lig = " class='even'";
				
				if (!empty($this->couleur_paire))
					$options_lig .= " bgcolor='$this->couleur_paire' ";
			}
			else if ($i % 2 == 1)
			{
				$options_lig = " class='odd'";

				if (!empty($this->couleur_impaire))
					$options_lig = " bgcolor='$this->couleur_impaire' ";
			}
			else 
				$options_lig = "";

			// Doit-on appliquer une option ?
			if (isSet($this->options[1][$cle_lig]))
			{
				foreach ($this->options[1][$cle_lig] as $option => $valeur)
					$options_lig .= " $option='$valeur' ";
			}
			
			$ligne = "<tr $options_lig>\n$ligne\n</tr>\n";

			// Prise en compte de la demande de répétition d'une ligne
			if (isSet($this->repetition_ligne[1][$cle_lig]))
			{
				$rligne = "";
				for ($i = 0; $i < $this->repetition_ligne[1][$cle_lig]; $i++)
					$rligne .= $ligne;
				
				$ligne = $rligne;
			}
			// On ajoute la ligne à la chaîne
			$chaine .= $ligne;
		}
		
		// Placement dans la balise <table>,  et retour
		return  "<table $this->options_tables>\n$chaine</table>\n";
	}
}
Et le code du script appelant la classe tableau :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//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>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<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");
			$tableauB->ajoutAttributsEntete(array("class" => "entete")) ;
			$tableauB->setAfficheEntete(2, true);
 
			$i = 0;
 
			// Recherche des films parisiens
			$resultat = $bd->execRequete("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);
 
				if ($i == 2)
					$tableauA->ajoutAttributsLigne($i, array("bgcolor" => "cyan"));
 
				// Second tableau : présentation par titre et par semaine
				$tableauB->ajoutEntete(2, $bo->semaine, "Semaine " . $bo->semaine);
				$tableauB->ajoutValeur($bo->titre, $bo->semaine, $bo->nb_entrees);
 
				if ($bo->semaine % 2 == 0)
					$tableauB->ajoutAttributsColonne($bo->semaine, array("bgcolor" => "pink"));
			}
 
			// Affichage des tableaux
			echo $tableauA->tableauHTML() . "<br />\n";
			echo $tableauB->tableauHTML() . "<br />\n";
		}
		catch (Exception $e)
		{
			// Une exception a été levée
			echo "<b>Erreur rencontrée : </b> " . $e->getMessage() . "\n";
		}
	?>
	</body>
</html>
Pouvez-vous me dire en quoi je fais fausse route ?