OVH Cloud OVH Cloud

modifier une liste de valeurs

14 réponses
Avatar
Olivier Masson
Bonjour,

pour une utilisateur donné, j'associe une liste de valeur.
Cette liste peut varier en longueur.
Je dois ensuite stocker cette liste dans une table MySQL.

Pour faire ceci, j'utilise un array, auquel :
- j'empêche d'ajouter un doublon avec in_array (plutôt que d'utiliser
array_unique à la fin)
- j'ajoute des éléments par array_push
- je supprime une valeur donnée d'abord en la cherchant avec
array_search puis en l'effaçant avec unset (j'ai pensé à array_filter
également).

Puis je 'serialize' le tableau pour le placer dans un champ MySQL.

Ca me parait bizarre comme façon de faire et comme mon niveau en php
n'est pas brillant, je voulais savoir comment mieux faire (sans utiliser
d'array ? en utilisant mieux MySQL ? SQLite (mais bof parce que pas
facilement dispo) ?).

Merci.

10 réponses

1 2
Avatar
Denis Beauregard
Le 29 Jun 2006 21:53:39 GMT, Olivier Masson
écrivait dans fr.comp.lang.php:

Bonjour,

pour une utilisateur donné, j'associe une liste de valeur.
Cette liste peut varier en longueur.
Je dois ensuite stocker cette liste dans une table MySQL.

Pour faire ceci, j'utilise un array, auquel :
- j'empêche d'ajouter un doublon avec in_array (plutôt que d'utiliser
array_unique à la fin)
- j'ajoute des éléments par array_push
- je supprime une valeur donnée d'abord en la cherchant avec
array_search puis en l'effaçant avec unset (j'ai pensé à array_filter
également).

Puis je 'serialize' le tableau pour le placer dans un champ MySQL.

Ca me parait bizarre comme façon de faire et comme mon niveau en php
n'est pas brillant, je voulais savoir comment mieux faire (sans utiliser
d'array ? en utilisant mieux MySQL ? SQLite (mais bof parce que pas
facilement dispo) ?).


avec implode et explode peut-être ?

si la liste est toto, tutu, tata, tu la transformes en
:toto:tutu:tata:

puis avec un str_replace, tu enlèves par exemple tata en
remplaçant :tata: par :


Denis

Avatar
Olivier Masson

avec implode et explode peut-être ?

si la liste est toto, tutu, tata, tu la transformes en
:toto:tutu:tata:

puis avec un str_replace, tu enlèves par exemple tata en
remplaçant :tata: par :



Ca n'utilise pas de tableau, c'est une autre solution.
Et ça évite le (un)serialize, c'est bien.

Merci pour la piste.

Avatar
Bruno Desthuilliers
Olivier Masson wrote:

avec implode et explode peut-être ?

si la liste est toto, tutu, tata, tu la transformes en
:toto:tutu:tata:

puis avec un str_replace, tu enlèves par exemple tata en
remplaçant :tata: par :



Ca n'utilise pas de tableau, c'est une autre solution.
Et ça évite le (un)serialize, c'est bien.


Non. C'est tout aussi inepte.

Merci pour la piste.


Tu ne devrais pas le remercier.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Bruno Desthuilliers
Denis Beauregard wrote:
Le 29 Jun 2006 21:53:39 GMT, Olivier Masson
écrivait dans fr.comp.lang.php:


pour une utilisateur donné, j'associe une liste de valeur.
Cette liste peut varier en longueur.
Je dois ensuite stocker cette liste dans une table MySQL.

(snip)



Puis je 'serialize' le tableau pour le placer dans un champ MySQL.

Ca me parait bizarre comme façon de faire et comme mon niveau en php
n'est pas brillant, je voulais savoir comment mieux faire (sans utiliser
d'array ? en utilisant mieux MySQL ? SQLite (mais bof parce que pas
facilement dispo) ?).



avec implode et explode peut-être ?

si la liste est toto, tutu, tata, tu la transformes en
:toto:tutu:tata:

puis avec un str_replace, tu enlèves par exemple tata en
remplaçant :tata: par :


Alors là, bravo. Purement brillant. Une idée de génie. Excellent
conseil. Tant qu'il y en aura pour le suivre, on n'a rien à craindre de
leur concurrence. Faut juste prier pour pas avoir à reprendre le projet
et la base qui va avec...

Je me tape de la maintenance sur une appli développée par un autre génie
qui a eu la même lumineuse idée, et j'ai plusieurs fois par jour des
envies de meutre.

Denis, si c'est tout ce que tu a comme conseils à donner, soit gentil,
abstiens-toi.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Bruno Desthuilliers
Olivier Masson wrote:
Bonjour,

pour une utilisateur donné, j'associe une liste de valeur.
Cette liste peut varier en longueur.
Je dois ensuite stocker cette liste dans une table MySQL.

Pour faire ceci, j'utilise un array, auquel :
- j'empêche d'ajouter un doublon avec in_array (plutôt que d'utiliser
array_unique à la fin)
- j'ajoute des éléments par array_push
- je supprime une valeur donnée d'abord en la cherchant avec
array_search puis en l'effaçant avec unset (j'ai pensé à array_filter
également).

Puis je 'serialize' le tableau pour le placer dans un champ MySQL.


fu2 http://thedailywtf.com/

Ca me parait bizarre comme façon de faire


C'est un euphémisme

et comme mon niveau en php
n'est pas brillant, je voulais savoir comment mieux faire (sans utiliser
d'array ? en utilisant mieux MySQL ?


Bingo.

SQLite (mais bof parce que pas
facilement dispo) ?).


Qu'est-ce que ça changerait de ce point de vue ? Les deux sont des bases
SQL.

Conseil n°1 : apprendre à concevoir un modèle de données relationnel.
Dans un modèle relationnel, un attribut doit être monovalué. Si tu a un
ensemble de valeurs a associer à un enregistrement, il faut le mettre
dans une autre table, avec une relation 1-N. Dans ton cas, ça donnerait
quelquechose comme :

table Utilisateur(*id_user*, nom, prenom, ...)
table ValeursUtilisateur(*id_valeur*, #id_user#, valeur)

Après, il te suffit de (SQL°:

insert into ValeursUtilisateur(id_user, valeur) values(XXX, YYY):
select id_valeur, valeur from ValeursUtilisateur where id_user=XXX;
update ValeursUtilisateur set valeur=ZZZ where id_valeur=???;



--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"

Avatar
Olivier Masson

Tu ne devrais pas le remercier.



:) Bon ok, je ne le remercie plus.

Pour revenir à ton post précédent, qui me dit de me tourner vers une
solution purement SQL, j'ai évoqué SQLite pour la raison suivante.
Si je fais comme tu l'indiques, ça va y aller à coup de INSERT. En plus,
il faudra chercher les doublons dans la base.
Or, les ajouts et suppression sur cette liste doivent se faire rapidement.
Bien sûr, je me doute bien que ce sera immédiat, mais dans tous les cas,
forcément plus long que de passer par une simple variable ou un tableau.
Ainsi, j'ai évoqué SQLite car c'est, il me semble, l'idéal pour ce genre
de table très petite aux requêtes simples.

Alors, déjà, pourquoi est-ce si atroce d'utiliser une variable ou un
tableau ? Sachant que les données sont gardées dans une session. Je
n'utilise MySQL que pour stocker la liste une fois qu'elle est confirmée
par l'utilisateur.
Si c'est uniquement la liste stockée dans la base qui te gêne, je peux
très bien stocker comme tu l'indiques lors du passage session -> base.

Qu'est-ce qui est gênant dans le fait de stocker ma liste dans un champ,
sachant que je n'ai *aucune* recherche à faire dans cette liste ? La
base me sert uniquement à stocker des listes en leur donnant un id. Je
pourrais utiliser des fichiers, mais je n'aime pas ça.

Avatar
Bruno Desthuilliers
Olivier Masson wrote:

Tu ne devrais pas le remercier.



:) Bon ok, je ne le remercie plus.

Pour revenir à ton post précédent, qui me dit de me tourner vers une
solution purement SQL,


Il ne s'agit pas de se tourner vers une solution "purement SQL", mais,
dans la mesure où tu utilise une base relationnelle, de l'utiliser
correctement.

j'ai évoqué SQLite pour la raison suivante.


Pour ce que j'en ai vu pour le moment, SQLite est un très bon choix pour
des petites bases. Mais du point de vue conception, ça ne change rien.

Si je fais comme tu l'indiques, ça va y aller à coup de INSERT.


Et UPDATE, ça sert à quoi ?

En plus,
il faudra chercher les doublons dans la base.


Gérer les contraintes d'unicité est une des responsabilités du SGBDR. La
solution canonique pour une table maître/esclave est d'avoir dans la
table esclave une clée unique composée de la clé externe pointant sur la
table maître et d'un numéro d'ordre.

Or, les ajouts et suppression sur cette liste doivent se faire rapidement.
Bien sûr, je me doute bien que ce sera immédiat, mais dans tous les cas,
forcément plus long que de passer par une simple variable ou un tableau.


Si ton schema est correct, tu ne devrais pas voir la différence.

Ainsi, j'ai évoqué SQLite car c'est, il me semble, l'idéal pour ce genre
de table très petite aux requêtes simples.


SQLite est idéal pour des petites bases embarquées. Si SQLite ne suffit
pas, c'est qu'il te faut un *vrai* SGBDR - auquel cas -> PostgreSQL.

Alors, déjà, pourquoi est-ce si atroce d'utiliser une variable ou un
tableau ?


Ai-je dis que c'était atroce ? Je ne parles pas de la représentation de
tes données en PHP durant l'exécution de ton script, mais du schema de
la base relationelle.

Sachant que les données sont gardées dans une session.


Attention à ne pas abuser des sessions. Elles sont bien sûr utiles
(voire nécessaires), mais moins tu t'en sers, mieux tu te portes.

Je
n'utilise MySQL que pour stocker la liste une fois qu'elle est confirmée
par l'utilisateur.


Une base relationelle est bien plus qu'un moyen de persistence.

Si c'est uniquement la liste stockée dans la base qui te gêne,


Tant que je n'ai pas à maintenir ton programme, ce n'est pas *moi* que
ça gêne...

je peux
très bien stocker comme tu l'indiques lors du passage session -> base.


C'est ton intérêt.

Qu'est-ce qui est gênant dans le fait de stocker ma liste dans un champ,
sachant que je n'ai *aucune* recherche à faire dans cette liste ?


Pour le moment... Et puis un de ces quatres, tu va avoir de la
maintenance à faire sur la base, on va te demander des stats, le besoin
va évoluer... Bref, tu va te retrouver dans la m... avec ton schéma
dénormalisé. Relis ton post, tu verra que tu es *déjà* en train de
réinventer la roue (carrée) au lieu de faire faire le boulot à ton SGBDR.

La
base me sert uniquement à stocker des listes en leur donnant un id.


Oui, et tu te retrouve à gérer manuellement les contraintes d'intégrité
et d'unicité - ce qui est le boulot d'une base relationelle...

Je
pourrais utiliser des fichiers, mais je n'aime pas ça.


Pourquoi ?-)

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Olivier Masson

Et UPDATE, ça sert à quoi ?



C'est jouer sur les mots ; bien évidemment, il était question d'UPDATE.


Si ton schema est correct, tu ne devrais pas voir la différence.


Alors là, c'est moi qui me permets de te corriger sur le même cas de
figure que tu envisages : aujourd'hui, je ne verrais pas la différence.
Mais si demain j'ai 1000 requêtes/seconde, entre un simple traitement de
chaine et un UPDATE, je peux déjà te dire - pour avoir fait des
benchmark là-dessus - que je gagnerais *beaucoup* en vitesse à passer
par la variable.


Ai-je dis que c'était atroce ? Je ne parles pas de la représentation de
tes données en PHP durant l'exécution de ton script, mais du schema de
la base relationelle.


Là ok, mais ce n'était pas vraiment le but de ma question.
Savoir à quoi peut servir un SGBDR et comment l'utiliser, c'est une
question que j'aurais posée sur f.c.a.sgbd.

Une base relationelle est bien plus qu'un moyen de persistence.


Oui, et alors ? Puisque, en l'occurrence, je n'ai et n'aurai besoin que
de ça.
Comme tu le dis, 'Pour le moment...', mais il suffisait de donner ça
comme argument, pas de m'expliquer qu'une base de données, c'est mieux
qu'une variable (alors que ça n'a aucun rapport). Et là, ça me fait
réfléchir.


Pourquoi ?-)


Parce que j'ai toujours considéré ça comme trop long et pas assez sûr.
Mais je me trompe probablement.

Avatar
Denis Beauregard
Le 30 Jun 2006 15:51:18 GMT, Bruno Desthuilliers
écrivait dans fr.comp.lang.php:

Olivier Masson wrote:

avec implode et explode peut-être ?

si la liste est toto, tutu, tata, tu la transformes en
:toto:tutu:tata:

puis avec un str_replace, tu enlèves par exemple tata en
remplaçant :tata: par :



Ca n'utilise pas de tableau, c'est une autre solution.
Et ça évite le (un)serialize, c'est bien.


Non. C'est tout aussi inepte.

Merci pour la piste.


Tu ne devrais pas le remercier.


J'ai pourtant essayé de répondre aux besoins qu'il a exprimé.

- Il cherche une solution simple. Ce que je lui suggère: utiliser
une chaîne, ajouter un élément à la fin ($a = $a . $b), et enlever
un élément en double (en fait, enlever l'élément d'abord avec le
str_replace, puis l'ajouter en concaténant). Il trouve trop
compliqué de le faire avec des arrays.
- La solution proposée est facile à mettre en oeuvre et à déboguer.
Il suffit d'un simple echo pour voir la chaîne avant et après.
- La solution proposée n'impose pas de changement de forme de
représentation (on n'a pas besoin de faire: extraire de la base
SQL, transformer en array, faire le traitement, transformer de
nouveau en chaîne, insérer dans la base SQL).

Comme c'est plus simple, c'est aussi plus facile de comprendre ce
qui se fait et par conséquent, plus facile de maintenir (?) le code.


Denis



Avatar
Olivier Masson

- Il cherche une solution simple. Ce que je lui suggère: utiliser
une chaîne, ajouter un élément à la fin ($a = $a . $b), et enlever
un élément en double (en fait, enlever l'élément d'abord avec le
str_replace, puis l'ajouter en concaténant). Il trouve trop
compliqué de le faire avec des arrays.


Hein ???
Je copie/colle pour les sourds des yeux : "je voulais savoir comment
mieux faire (sans utiliser d'array ? en utilisant mieux MySQL ? SQLite
(mais bof parce que pas facilement dispo) ?)".

Tu vois quelque part que je suis dépassé par l'extrême complexité des
tableaux toi ?

Je ne cherche pas à faire au plus simple, je cherche à faire *au mieux*
(ce qui peut tout à fait être le plus simple.)

1 2