Keyser Soze Posté 24 Mars 2007 Posté 24 Mars 2007 Bonjour à tous ! Pour une appli de gestion des stocks, je crée un array à partir des données d'une table. Je récupère l'id produit ainsi que les valeurs des options (couleurs et tailles) pour chaque produit. Ce tableau multi-dimensions, une fois créé, se présente ainsi (exemple sur deux produits) et est stocké dans une variable $tableau : array(array(102,array(10,11,13,14,49,50),array(1,2,5,6,7,8)),array(183,array(41,44,47,50),array(5,6,7,8))) Ce code fonctionne très bien lorsque je code "en dur" $tableau : $ tableau = array(array(102,array(10,11,13,14,49,50),array(1,2,5,6,7,8)),array(183,array(41,44,47,50),array(5,6,7,8))) Voici le code que j'utilise pour l'exploiter : function afficher_tableau($tableau) { // on fait une boucle qui lit les éléments du tableau foreach ($tableau as $cle=>$valeur) { // si l'un des éléments est lui même un tableau // alors on applique la fonction à ce tableau if(is_array($valeur)) { // on affiche le nom de la clé et // le début d'une liste pour // décaler le contenu vers la droite echo $cle.' : <ul>'; // ici se réalise la récursivité // c'est à dire qu'on applique la fonction // à l'élément en cours car c'est lui aussi un tableau afficher_tableau($valeur); // on ferme la liste echo '</ul>'; } // si ce n'est pas un tableau // alors on affiche le contenu de l'élément else { echo $cle.' = '.$valeur.' <br>'; } } } Seulement, lorsque je veux exploiter le $tableau créé à partir de ma requête SQL, je me retouve avec cette erreur : Warning: Invalid argument supplied for foreach() in etc... Logique, puisque lorsque je fais un gettype(), il me retourne qu'il s'agit d'un type String. Forcer le type par un settype($tableau, "array"); ne fonctionne pas. Des idées ? Merci d'avance ! (testé sous PHP 4.3.0 et 5.x)
Sarc Posté 24 Mars 2007 Posté 24 Mars 2007 Salut Effectivement ce code marche bien, et c'est donc le code qui crée le tableau qui ne marche pas... Mais tu ne nous le donnes pas, donc on va pas pouvoir t'aider Donne donc le code qui te crée le tableau à partir de ta base c'est de là que vient l'erreur.
Keyser Soze Posté 24 Mars 2007 Auteur Posté 24 Mars 2007 (modifié) Merci de ta réponse Sarc, pour moi, la "création" de l'array fonctionne, je la vérifie par un echo qui m'affiche bien ce que j'attendais... mais j'ai (forcément) loupé qq chose voici donc le code intégral de la page : <?php// on se connecte à MySQL$db = mysql_connect('localhost', 'root', ''); // connexion en local// on sélectionne la basemysql_select_db('mabase',$db);// on crée la requête SQL$sql = 'SELECT * FROM products_attributes ORDER BY products_id, options_id, options_values_id';// on envoie la requête$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());$total = mysql_num_rows($req); // nb total d'enregistrements?> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /></head><body><?// initialisation des compteurs$enregistrement=0;$id_produit_old = 0;$id_option_old = 0;// on fait une boucle qui va faire un tour pour chaque enregistrement// début de la boucle, on initialise la chaine avec le tableau principal ($product_attributes_chaine = 'array(';while($data = mysql_fetch_assoc($req)){// on doit arriver à un tableau de ce genre :// $product_attributes = array(array (products_id1,array(options_values_id où options_id=1,...),array(options_values_id où options_id=2, ...)), array( array(products_id2,array(options_values_id où options_id=1,...),array(options_values_id où options_id=2, ...)));// on incrémente le compteur d'enregistrements$enregistrement ++;$id_produit = $data['products_id']; $id_option = $data['options_id'];$options_values_id = $data['options_values_id']; switch($id_produit_old) // on vérifie l'id produit { case 0: // premier enregistrement -> on commence un nouveau tableau $product_attributes_chaine .= 'array(' . $id_produit . ',array(' . $options_values_id; $id_produit_old = $id_produit; $id_option_old = $id_option; break; case $id_produit: // on est sur le même produit -> on continue le tableau switch($id_option_old) // on vérifie l'id_option_old { case 0: // première boucle -> on pose la première valeur $product_attributes_chaine .= $options_values_id; $id_option_old = $id_option; break; case $id_option: // on est toujours sur le meme numero d'option -> on continue le tableau switch ($enregistrement) // on vérifie le n° d'enregistrement { case $total: // on a atteint le dernier enregistrement, on clôt tous les array $product_attributes_chaine .= ',' . $options_values_id . ')))'; $id_option_old = $id_option; break; default: // ce n'est pas le dernier enregistement, on continue le tableau $product_attributes_chaine .= ',' . $options_values_id; $id_option_old = $id_option; break; } break; default: // on change de numero d'option switch($id_option) // on vérifie l'id_option { case 2: // si l'id_option passe de 1 à 2, on ferme le premier tableau et on commence le second $product_attributes_chaine .= '),array(' . $options_values_id; $id_option_old = $id_option; break; case 1: // si l'id_option passe de 2 à 1, on ferme le second tableau et on recommence un array avec le nouveau products_id $product_attributes_chaine .= '),array(' . $id_produit . ',array(' . $options_values_id; $id_option_old = $id_option; break; } // fin switch id_option break; } // fin switch id_option_old $id_produit_old = $id_produit; break; default: //on change de produit // si c'est le dernier produit de la table, on ferme le second tableau $product_attributes_chaine .= ')'; $id_produit_old = $id_produit; break; }}// fermeture du while// on ferme la connexion à mysqlmysql_close();// le tableau complet est dans $product_attributes_chaineecho $product_attributes_chaine; // affichage de vérification du tableau, il me donne bien ce que j'escomptais...$chaine = $product_attributes_chaine;echo "<br>type " . gettype( $chaine ) . "<br />\n"; afficher_tableau($chaine); function afficher_tableau($tableau) {// if (is_array($tableau))// { // on fait une boucle qui lit les éléments du tableau foreach ($tableau as $cle=>$valeur) { // si l'un des éléments est lui même un tableau // alors on applique la fonction à ce tableau if(is_array($valeur)) { // on affiche le nom de la clé et // le début d'une liste pour // décaler le contenu vers la droite echo $cle.' : <ul>'; // ici se réalise la récursivité // c'est à dire qu'on applique la fonction // à l'élément en cours car c'est lui aussi un tableau afficher_tableau($valeur); // on ferme la liste echo '</ul>'; } // si ce n'est pas un tableau // alors on affiche le contenu de l'élément else { echo $cle.' = '.$valeur.' <br>'; } } // } } ?></table></body></html> Modifié 24 Mars 2007 par Keyser Soze
Sarc Posté 24 Mars 2007 Posté 24 Mars 2007 Tu as le BBCode [ codebox ] [/ codebox ] pour les longs codes, si tu veux, ça évite de devoir défiler sur toute la page pour lire les réponses d'après pour moi, la "création" de l'array fonctionne, je la vérifie par un echo qui m'affiche bien ce que j'attendais... mais j'ai (forcément) loupé qq chose C'est bien ce qui m'inquiétais, tu ne crées qu'une chaîne de caractère qui donne le code de création d'un tableau en PHP, mais tu ne crées pas un tableau ! Voilà pourquoi ça pose problème... Ton code est assez compliqué et je n'ai pas le temps de le parcourir en profondeur, mais tu sais ce qu'il faut pour créer un tableau... Par exemple : // Construction d'un sous-tableau$soustab1 = array('1', '2', '3');// Rajout de ce sous-tableau à la suite du tableau principal$tableau[] = $soustab1; Voilà ce que tu dois faire, commencer par construire tes sous-tableaux, puis construire ton tableau principal du genre $tableau = array($soustab1, $soustab2); Et si tu veux rajouter un élément dans ce tableau, tu fais : $tableau[] = $soustab3; Voilà en gros comment revoir ton code Bonne chance !
Keyser Soze Posté 24 Mars 2007 Auteur Posté 24 Mars 2007 Effectivement... ta solution me semble tellement évidente que je me demande pourquoi je n'y ai pas pensé ! *va se flageller avec une botte d'orties et revient* Je la teste ce soir et je te dis ce qu'il en est. Merci encore pour cette illumination !
Keyser Soze Posté 26 Mars 2007 Auteur Posté 26 Mars 2007 (modifié) Voici le code qui fonctionne (grâce aux lumières de Sarc ) Je le poste pour ceux qui seraient confrontés au même type de problème. Son utilité ? Pour les sites marchands sous OS Commerce lorsque vous vous retrouvez confrontés à une demande de gestion précise des stocks où, pour chaque article, vous devez connaître les quantités disponibles pour chaque déclinaison de couleurs et de tailles entre elles... Le développement de l'appli est en cours, ceci en constitue la première partie. Encore merci pour le coup de main ! <?php// on se connecte à MySQL$db = mysql_connect('localhost', 'root', ''); // local// on sélectionne la basemysql_select_db('mabase',$db);// on crée la requête SQL$sql = 'SELECT * FROM products_attributes ORDER BY products_id, options_id, options_values_id';// on envoie la requête$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());$total = mysql_num_rows($req); // nb total d'enregistrements?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>Constitution Tableau</title></head><body><?// initialisations$compteur = 0;$id_produit_old = 0;$tableau = array();$soustableau1 = array();$soustableau2 = array();$soustableau3 = array();$soustableau4 = array();// on fait une boucle qui va faire un tour pour chaque enregistrementwhile($data = mysql_fetch_assoc($req)){// incrémentation compteur$compteur ++;$id_produit = $data['products_id']; $id_option = $data['options_id'];$id_valeur_option = $data['options_values_id'];echo $id_produit . "-" . $id_option . "-" . $id_valeur_option . "<br>";switch($id_produit) // on vérifie l'id produit{case $id_produit_old: // on continue le meme produit switch ($id_option) // on vérifie le numero d'option et on l'ajoute au sous tableau concerné { case 1: // $soustableau1[] = $id_valeur_option ; break; case 2: // $soustableau2[] = $id_valeur_option ; break; case 3: // $soustableau3[] = $id_valeur_option ; break; case 4: // $soustableau4[] = $id_valeur_option ; }// fermeture du switch $id_option switch ($compteur) // on vérifie si c'est le dernier enregistrement { case $total:// on arrive au dernier produit $tableau[$id_produit] = array(1=>$soustableau1,2=>$soustableau2, 3=>$soustableau3, 4=>$soustableau4); }break; // break $id_produit_oldcase ($id_produit_old != $id_produit) : // on change de produit ou on commence le tableau switch ($compteur) { case 1: // on commence le tableau switch ($id_option) // on vérifie le numero d'option et on l'ajoute au sous tableau concerné { case 1: // $soustableau1[] = $id_valeur_option ; break; case 2: // $soustableau2[] = $id_valeur_option ; break; case 3: // $soustableau3[] = $id_valeur_option ; break; case 4: // $soustableau4[] = $id_valeur_option ; }// fermeture du switch $id_option break; case $total:// on arrive au dernier produit switch ($id_option) // on vérifie le numero d'option et on l'ajoute au sous tableau concerné { case 1: // $soustableau1[] = $id_valeur_option ; break; case 2: // $soustableau2[] = $id_valeur_option ; break; case 3: // $soustableau3[] = $id_valeur_option ; break; case 4: // $soustableau4[] = $id_valeur_option ; }// fermeture du switch $id_option $tableau[$id_produit] = array(1=>$soustableau1,2=>$soustableau2, 3=>$soustableau3, 4=>$soustableau4); break; default: // on change de produit $tableau[$id_produit_old] = array(1=>$soustableau1,2=>$soustableau2, 3=>$soustableau3, 4=>$soustableau4); // on réinitialise le contenu des sous tableaux $soustableau1 = array(); $soustableau2 = array(); $soustableau3 = array(); $soustableau4 = array(); switch ($id_option) // on vérifie le numero d'option et on l'ajoute au sous tableau concerné { case 1: // $soustableau1[] = $id_valeur_option ; break; case 2: // $soustableau2[] = $id_valeur_option ; break; case 3: // $soustableau3[] = $id_valeur_option ; break; case 4: // $soustableau4[] = $id_valeur_option ; }// fermeture du switch $id_option }$id_produit_old = $id_produit ;}// fermeture du switch $id_produit }// fermeture du while// on ferme la connexion à mysqlmysql_close();// le tableau complet est dans $tableauafficher_tableau($tableau); function afficher_tableau($array) {// if (is_array($tableau))// { // on fait une boucle qui lit les éléments du tableau foreach ($array as $cle=>$valeur) { // si l'un des éléments est lui même un tableau // alors on applique la fonction à ce tableau if(is_array($valeur)) { // on affiche le nom de la clé et // le début d'une liste pour // décaler le contenu vers la droite echo $cle.' : <ul>'; // ici se réalise la récursivité // c'est à dire qu'on applique la fonction // à l'élément en cours car c'est lui aussi un tableau afficher_tableau($valeur); // on ferme la liste echo '</ul>'; } // si ce n'est pas un tableau // alors on affiche le contenu de l'élément else { echo $cle.' = '.$valeur.' <br>'; } } // } } ?></table></body></html> Modifié 26 Mars 2007 par Keyser Soze
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant