Page 1 sur 1

Enregistrer un tableau dans MySQL

Publié : 12 avr. 2005, 22:13
par calimo
Bonsoir !

J'aimerais savoir comment enregistrer un tableau (array) dans un champ de données MySQL. Est-ce possible ? Ou suis-je obligé d'utiliser plusieurs champs ?

J'explique un peu ce que je veux faire.
C'est pour le fil RSS des extensions. Le but est de signaler dans le flux avec quoi l'extension fonctionne (FF, Nvu, ...).

Donc j'ai un formulaire avec des cases à cocher, une pour chaque "produit".
Je récupère donc les données, et j'ai le script suivant :

Code : Tout sélectionner

$i=0;
$pour=array();
if ($firefox) {
	$i=$i+1;
	$pour[$i]="Firefox";
}
if ($thunderbird) {
	$i=$i+1;
	$pour[$i]="Thunderbird";
}
if ($nvu) {
	$i=$i+1;
	$pour[$i]="Nvu";
}
if ($suite) {
	$i=$i+1;
	$pour[$i]="Mozilla";
}
Qui me fait un magnifique tableau. Ensuite le but est dans le fil RSS (1.0) de faire la chose suivante :

Code : Tout sélectionner

foreach ($pour as $i) {
	print "<dc:subject>$pour[$i]</dc:subject>";
}
J'ai regardé du côté des types "enum" ou "set" mais ça ne semble pas ça, je veux stocker vraiment mon tableau, pas "Firefox,Thunderbird" etc.

Alors comment faire ? Faut-il faire une transformation en texte et refaire par la suite un tableau ? Merci d'avance :wink:

Publié : 12 avr. 2005, 22:42
par netfab
Bonsoir,

Si tu veux vraiment faire propre, je pense qu'il faudrait plutôt créer dans ta table SQL un champs de type bool par application, ce qui serait beaucoup plus simple en cas d'éventuelles modifications par la suite (et même pour la sélection).

********** | FF | NVU | Thunderbird | MozSuite
extension 1 | true | false | true | true
extension 2 | false | true | false | false
extension 3 | true | true | false | true

MySQL est fait pour çà, alors autant en profiter.

Publié : 13 avr. 2005, 10:32
par martin
Si tu tiens vraiment à enregistrer ton array tel quel dans la base mysql, il te faut effectivement le transformer en "texte" avant avec la fonction serialize(), puis tu le stockes dans un champ de type text (a priori tu ne connais pas le nombre de caractères généré par serialize).

Avec la fonction unserialize() tu récupères exactement ton tableau dans le sens inverse.

Publié : 13 avr. 2005, 15:08
par calimo
NetFab a écrit :Si tu veux vraiment faire propre, je pense qu'il faudrait plutôt créer dans ta table SQL un champs de type bool par application, ce qui serait beaucoup plus simple en cas d'éventuelles modifications par la suite (et même pour la sélection).
Ou plutôt les ajouter à la table déjà existante. Mais ça risque de multiplier les champs...
martin a écrit :Si tu tiens vraiment à enregistrer ton array tel quel dans la base mysql, il te faut effectivement le transformer en "texte" avant avec la fonction serialize(), puis tu le stockes dans un champ de type text (a priori tu ne connais pas le nombre de caractères généré par serialize).

Avec la fonction unserialize() tu récupères exactement ton tableau dans le sens inverse.
Arf, une transformation en plus :(


Merci à tous les deux pour vos réponses. À votre avis, quelle est la meilleure solution ? Je penche pour la première...

Publié : 13 avr. 2005, 15:55
par Benoit
Un truc tout bête que je fais parfois c'est stocker la liste de valeurs dans un champ texte (varchar) et puis utiliser explode pour en faire un tableau (et implode au moment de l'enregistrement).

Publié : 13 avr. 2005, 16:42
par calimo
Euh, question conne... comment on crée un champ booléen ? J'ai plein de types, des varchar, int, enum, set mais je ne vois pas de "bool" ou de truc du genre :shock:

Publié : 13 avr. 2005, 16:46
par Benoit
un champ booléen c'est équivalent à ENUM('false','true') :)

Publié : 13 avr. 2005, 16:47
par calimo
Ah ben ça tombe bien c'est ce que j'avais fait en attendant :lol:

Bon, ça marche exactement comme je voulais, mais je vais quand-même essayer les autres méthodes (mais plus tard...)

Publié : 13 avr. 2005, 21:45
par calimo
Je crois que je vais garder la technique du "explode", je ne me rends pas trop conte au niveau du serveur ce qui est le mieux, mais je pense que l'appel de 4 champs dans la requête SQL puis une suite de 4 "if" pour chaque élément est moins économique, et en tous cas moins élégant qu'1 appel, 1 explode et 1 boucle foreach... je peux me tromper :roll:

Au passage est-ce qu'il y a un moyen de simplifier ça :

Code : Tout sélectionner

   foreach ($pour as $key=>$value) {
	   echo '<dc:subject>' . $pour[$key] .'</dc:subject>' . "\n";
   }
Si je mets

Code : Tout sélectionner

   foreach ($pour as $i) {
	   echo '<dc:subject>' . $pour[$i] .'</dc:subject>' . "\n";
   }
ça ne marche pas, j'ai un "undefined index" parce qu'il va chercher $pour["Firefox"] au lieu de $pour["0"] etc.
Est-ce normal ? Ça me paraît contre-intuitif, quand on a un truc de ce genre on va chercher $pour[1], $pour[2] etc, pas les valeurs qu'ils prennent... si ?

Publié : 13 avr. 2005, 22:12
par bobo
calimo a écrit :Au passage est-ce qu'il y a un moyen de simplifier ça :

Code : Tout sélectionner

   foreach ($pour as $key=>$value) {
	   echo '<dc:subject>' . $pour[$key] .'</dc:subject>' . "\n";
   }
Si je mets

Code : Tout sélectionner

   foreach ($pour as $i) {
	   echo '<dc:subject>' . $pour[$i] .'</dc:subject>' . "\n";
   }
ça ne marche pas, j'ai un "undefined index" parce qu'il va chercher $pour["Firefox"] au lieu de $pour["0"] etc.
Est-ce normal ? Ça me paraît contre-intuitif, quand on a un truc de ce genre on va chercher $pour[1], $pour[2] etc, pas les valeurs qu'ils prennent... si ?
Le but premier de l'instruction foreach est de parcourir les éléments sans se préoccuper des index.
Si tu utilise la syntaxe $key=>$value, $key contient la clé, et $value contient la valeur. Inutile alors de passer par l'objet tableau car $value == $pour[$key]. Le fait d'obtenir la clé est un bonus.
La syntaxe simplifiée ne donne accès qu'à la valeur, car très souvent l'index n'a pas d'importance. Donc ton code peut s'écrire :

Code : Tout sélectionner

   foreach ($pour as $value) {
	   echo '<dc:subject>' .$value .'</dc:subject>' . "\n";
   }

Publié : 13 avr. 2005, 22:36
par calimo
Arf je savais que c'était possible, et c'était beaucoup plus simple que je ne le pensais :lol:
D'ailleurs j'aurais du y penser vu que $pour[$value] allait chercher $pour["Firefox"] donc forcément :oops:

À vrai dire je suis toujours perturbé par le Pascal que j'ai appris tout récemment (enfin, les bases), il y a des ressemblances terribles, sauf quelques trucs comme ça que je mélange irrémédiablement :(

Merci en tous cas, maintenant tout est parfait je crois :D

Publié : 14 avr. 2005, 00:56
par martin
un champ booléen c'est équivalent à ENUM('false','true')
arf, désolé, j'aime pas trop... Le type enum a priori est efficace dans mysql, mais il n'est pas "standard", c'est à dire qu'il ne pourra pas forcément être porté sur une autre base. Visiblement il n'existe pas de type booléen dans la norme sql. Une autre solution c'est un tinyint non signé, 0 pour faux, n'importe quelle autre valeur par exemple 1 pour vrai.

Sinon,
1 appel, 1 explode et 1 boucle foreach
tout autant économique que 1 appel, 1 unserialize, et 1 boucle foreach. Mais bon, dans les 2 cas c'est pas très propre au niveau modélisation des données (mais surement efficace).