Précédent   Forum du club des développeurs et IT Pro > PHP > PHP & SGBD > PHP & PostgreSQL
PHP & PostgreSQL Forum d'entraide sur PostgreSQL avec PHP. Avant de poster -> FAQ PostgreSQL, Cours PostgreSQL. Pour les questions concernant le moteur PostgreSQL plutôt que les fonctions PHP, merci d'utiliser le forum PostgreSQL.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 27/06/2012, 09h11   #1
cyscek
Invité régulier
 
Inscription : janvier 2008
Messages : 78
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 78
Points : 8
Points : 8
Par défaut update d'array et virgule

Bonjour à tous !

J'étais venu il y a quelques temps parce que je ne comprenais pas comment mettre à jour un array dans ma table, et on m'avait fait part d'une solution :

Code :
1
2
3
4
$listusers[] = $user;
$tab = implode(',',$listeusers);
		$query = 'UPDATE users SET list = {'.$tab.'}  WHERE city=\''.$city.'\'';
		$result = pg_query($query) or die('Échec de la requête : ' . pg_last_error());
En utilisant le implode, j'ai effectivement eu le comportement que je voulais.

Sauf que depuis, je suis passé à une autre table, qui contient elle aussi un array, et là les valeurs dedans peuvent contenir des virgules. Du coup, je n'ai pas le résultats que je voudrais :

Citation:
{test, test1} en base, on veut ajouter "test2, le bon", on obtient :

{test, test1, test2, le bon}
J'aimerai pouvoir différencier chaque bloc, quitte à mettre un séparateur différent, mais comment puis-je faire ça ?
cyscek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 09h27   #2
selmouadin
Membre régulier
 
Homme Said ELMOUADIN
Développeur Web
Inscription : mai 2012
Messages : 57
Détails du profil
Informations personnelles :
Nom : Homme Said ELMOUADIN
Localisation : Maroc

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : mai 2012
Messages : 57
Points : 91
Points : 91
salut,

tu change le separateur
Code :
$tab = implode(';',$listeusers);
selmouadin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 09h36   #3
Fench
Expert Confirmé
 
Avatar de Fench
 
Homme
Chercheur en informatique
Inscription : mai 2002
Messages : 2 346
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Groenland

Informations professionnelles :
Activité : Chercheur en informatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2002
Messages : 2 346
Points : 3 231
Points : 3 231
Ca marchera pas puisque il faut absolument des virgules pour la requête ...

Il faut donc que tu échapes les , contenu dans ton tableau, regardes dans les str_replace ...
__________________
Meuuh en AI à l'INRA
Domaines: {java, php, js, jquery}{hibernate, doctrine}{MyLib, symfony, Zend}
fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes (balise à cliquer en bas de l'écran)
Fench est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 09h48   #4
cyscek
Invité régulier
 
Inscription : janvier 2008
Messages : 78
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 78
Points : 8
Points : 8
Donc que j'utilise str_replace, pour mettre un caractère que les utilisateurs n'iront pas mettre normalement dans cette chaîne là, c'est ça ?
cyscek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 10h06   #5
Fench
Expert Confirmé
 
Avatar de Fench
 
Homme
Chercheur en informatique
Inscription : mai 2002
Messages : 2 346
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Groenland

Informations professionnelles :
Activité : Chercheur en informatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2002
Messages : 2 346
Points : 3 231
Points : 3 231
J'essayerais 2 solutions:
1) Remplacer les , qui sont dans les $listeUsers[i] par un $listeUsers[i] = str_replace(",", "\,", $listeUsers[i]); dans une boucle. Puis dans l'autre sens quand tu liras la base.

2) Regarder une fonction qui échape les , dans ce cas là
__________________
Meuuh en AI à l'INRA
Domaines: {java, php, js, jquery}{hibernate, doctrine}{MyLib, symfony, Zend}
fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes (balise à cliquer en bas de l'écran)
Fench est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 10h08   #6
stealth35
Modérateur
 
Inscription : septembre 2010
Messages : 7 958
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 958
Points : 9 508
Points : 9 508
Faut faire une table lié c'est de la bidouille ce que tu fais
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 10h42   #7
Fench
Expert Confirmé
 
Avatar de Fench
 
Homme
Chercheur en informatique
Inscription : mai 2002
Messages : 2 346
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Groenland

Informations professionnelles :
Activité : Chercheur en informatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2002
Messages : 2 346
Points : 3 231
Points : 3 231
Citation:
Envoyé par stealth35 Voir le message
Faut faire une table lié c'est de la bidouille ce que tu fais


Et donc deuxième solution, revenir comme avant une boucle sur le nbr d'éléments et de la concaténation
Code :
1
2
3
4
 
$query = "UPDATE users SET list = '";
foreach ($listeusers as $users)
    $query = $query.$users."', '";
Puis fin de requête en enlevant le dernier ", '" de trop (peut être voir plutôt une boucle while )
__________________
Meuuh en AI à l'INRA
Domaines: {java, php, js, jquery}{hibernate, doctrine}{MyLib, symfony, Zend}
fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes (balise à cliquer en bas de l'écran)
Fench est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 10h47   #8
cyscek
Invité régulier
 
Inscription : janvier 2008
Messages : 78
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 78
Points : 8
Points : 8
Hm, je vais surement passer pour un inculte, mais je ne vois pas ce que tu entends par table liée ...

Là j'ai testé ça :

Code :
1
2
3
4
5
6
7
8
9
 
 
$listusers[] = $user;
for($te=0; $te < count($listusers); $te ++){
			$listusers[$te] = str_replace(",","/;/",$listusers[$te]);
}
$tab = implode(',',$listeusers);
		$query = 'UPDATE users SET list = {'.$tab.'}  WHERE city=\''.$city.'\'';
		$result = pg_query($query) or die('Échec de la requête : ' . pg_last_error());
Je remplace dans chaque élément les virgules par des /;/ (ça je suis sûr que les utilisateurs n'en mettront pas), et du coup je ferai la transformation inverse quand je le récupère . Parce que j'ai essayé avec le \, , mais l'implode met le bazar là dedans.
cyscek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 10h54   #9
stealth35
Modérateur
 
Inscription : septembre 2010
Messages : 7 958
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 958
Points : 9 508
Points : 9 508
Citation:
Envoyé par cyscek Voir le message
Hm, je vais surement passer pour un inculte, mais je ne vois pas ce que tu entends par table liée ...
Faire une jointure avec une autre table : list

list :
id, element, user_id
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 10h56   #10
Fench
Expert Confirmé
 
Avatar de Fench
 
Homme
Chercheur en informatique
Inscription : mai 2002
Messages : 2 346
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Groenland

Informations professionnelles :
Activité : Chercheur en informatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2002
Messages : 2 346
Points : 3 231
Points : 3 231
Oui en fait je pense que tu devrait plutôt faire la concaténation que ceci:
Code :
1
2
3
4
5
6
7
8
9
 
$listusers[] = $user;
for($te=0; $te < count($listusers); $te ++){
   $strFinal .= "'".$listusers[$te]."', ";
}
// Le dernier paramètre
$strFinal .= "'".$listusers[$te]."'";
$query='UPDATE users SET list = '.$strFinal.' WHERE city=\''.$city.'\'';
$result = pg_query($query) or die('Échec de la requête : ' . pg_last_error());
__________________
Meuuh en AI à l'INRA
Domaines: {java, php, js, jquery}{hibernate, doctrine}{MyLib, symfony, Zend}
fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes (balise à cliquer en bas de l'écran)
Fench est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 11h03   #11
cyscek
Invité régulier
 
Inscription : janvier 2008
Messages : 78
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 78
Points : 8
Points : 8
j'ai un doute sur ta proposition, c'est un contre exemple que tu donnes, ou tu as mis un "que" à la place d'un "comme" ? Parce que là c'est pas clair ^^
cyscek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 11h05   #12
stealth35
Modérateur
 
Inscription : septembre 2010
Messages : 7 958
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 958
Points : 9 508
Points : 9 508
Citation:
Envoyé par Fench Voir le message
Code :
1
2
3
4
5
 
$listusers[] = $user;
for($te=0; $te < count($listusers); $te ++){
   $strFinal .= "'".$listusers[$te]."', ";
}
foreach pour parcourir un array, de plus ton count n'est pas a la bonne position
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 11h25   #13
cyscek
Invité régulier
 
Inscription : janvier 2008
Messages : 78
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 78
Points : 8
Points : 8
J'ai essayé votre proposition, avec des ' . Mais dans la base, cela apparait comme {test, test1, test2} là où j'aurai voulu {"test, test1, test2"}. Je n'ai pas de moyen de regrouper après coup.

J'ai tenté de changer les ' par des ", j'ai à peu près le résultat voulu, sauf que le problème vient maintenant lors de la récupération.

Si j'ai par exemple en base :
{test, "test1, test2"}

je récupère ces valeurs, je veux en ajouter une, il me concatène de cette manière :

{"test", ""test1, test2"", "test3"}

Il faut que je teste pour voir si j'ai déjà des " ou non autour de ma valeur ...
cyscek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 11h25   #14
Fench
Expert Confirmé
 
Avatar de Fench
 
Homme
Chercheur en informatique
Inscription : mai 2002
Messages : 2 346
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Groenland

Informations professionnelles :
Activité : Chercheur en informatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2002
Messages : 2 346
Points : 3 231
Points : 3 231
Citation:
Envoyé par cyscek Voir le message
j'ai un doute sur ta proposition, c'est un contre exemple que tu donnes, ou tu as mis un "que" à la place d'un "comme" ? Parce que là c'est pas clair ^^
Oui 'comme' désolé ...

'contre exemple' pas compris ...

J'utilise le for à la place du foreach car il faut éviter la dernière ',' nous aurons pu utiliser un while aussi.

Citation:
de plus ton count n'est pas a la bonne position
Oui faut voir le nombre d'éléments (count-1 serait mieux car je souhaite garder le dernier élément pour terminer syntaxiquement la list dans le update)


C'est quoi le dernier code en date ?
__________________
Meuuh en AI à l'INRA
Domaines: {java, php, js, jquery}{hibernate, doctrine}{MyLib, symfony, Zend}
fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes (balise à cliquer en bas de l'écran)
Fench est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 11h32   #15
stealth35
Modérateur
 
Inscription : septembre 2010
Messages : 7 958
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 958
Points : 9 508
Points : 9 508
Citation:
Envoyé par Fench Voir le message
Oui 'comme' désolé ...

'contre exemple' pas compris ...

J'utilise le for à la place du foreach car il faut éviter la dernière ',' nous aurons pu utiliser un while aussi.
non le problème est le même avec le for

Citation:
Envoyé par Fench Voir le message
Oui faut voir le nombre d'éléments (count-1 serait mieux car je souhaite garder le dernier élément pour terminer syntaxiquement la list dans le update)
les boucle for avec count doivent être comme ça

Code :
for($te=0, $l = count($listusers); $te < $; $te++)
si vous voulez continuer dans votre bidouille il faut faire

Code :
1
2
3
4
5
6
$users = array();
foreach ($listeusers as $user) {
    $users[] = sprintf("'%s'", mysql_real_escape_string($user));
}
 
$users = implode(',', $users);
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 11h45   #16
cyscek
Invité régulier
 
Inscription : janvier 2008
Messages : 78
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 78
Points : 8
Points : 8
Avec ta solution stealth35, j'ai une erreur de syntaxe lors du query :

Code :
Query failed: ERREUR: erreur de syntaxe sur ou près de « test » LINE 1: UPDATE users SET list = '{'test','test1,test2'}'  WH...
cyscek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 11h52   #17
stealth35
Modérateur
 
Inscription : septembre 2010
Messages : 7 958
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 958
Points : 9 508
Points : 9 508
enlève les {}, faut aussi echappe les ' je pense, mais bon pourquoi tu fait pas un vrai schéma ?
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 12h01   #18
Fench
Expert Confirmé
 
Avatar de Fench
 
Homme
Chercheur en informatique
Inscription : mai 2002
Messages : 2 346
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Groenland

Informations professionnelles :
Activité : Chercheur en informatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2002
Messages : 2 346
Points : 3 231
Points : 3 231
Citation:
les boucle for avec count doivent être comme ça


Code :Sélectionner tout - Visualiser dans une fenêtre à partfor($te=0, $l = count($listusers); $te < $; $te++)
Tiens je connaissais pas parcontre il y a toujours un pb dans l'index (voir le -1)

Pour le reste, je sais pas si tout le monde est sur la même longueur d'onde

Tu pourais pas nous donner ton dernier code pour cette affaire (que ce soit la solution bidouillée ou celle non bidouillée ) histoire de finir, merci
__________________
Meuuh en AI à l'INRA
Domaines: {java, php, js, jquery}{hibernate, doctrine}{MyLib, symfony, Zend}
fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes (balise à cliquer en bas de l'écran)
Fench est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 12h14   #19
cyscek
Invité régulier
 
Inscription : janvier 2008
Messages : 78
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 78
Points : 8
Points : 8
Voilà où j'en suis :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
while ($row = pg_fetch_array($result)) {
			$listeusers[] = $row[3];	
		}
		$listeusers= pg_array_parse($listeusers[0], $asText = true);
		$listeusers[] = $listeuserstemp; // $listeuserstemp correspond à la nouvelle valeur à intégrer dans la liste
 
		$temp = array();
		foreach ($listeusers as $user) {
			$temp[] = sprintf("'%s'", mysql_real_escape_string($user));
		}
 
		$temp = implode(',', $temp);
 
		$query = 'UPDATE users SET list = \'{'.$temp.'}\' WHERE city=\''.$city.'\'';
Pour te répondre stealth35, c'est que je ne vois pas comment faire. Ma table contient les champs group, city et list. Elle doit juste me servir à regrouper des types d'utilisateurs selon leur groupe (super admin, admin, utilisateur privilégié, utilisateur de base).

Cette table ne me sert qu'à ça, avoir mes listes d'utilisateurs. Je ne sais pas comment faire comme tu disais avec une table liée, mais si on m'explique je veux bien tenter, moi je cherchais sur cette méthode parce que je ne sais pas faire autrement .
cyscek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 13h09   #20
rawsrc
Modérateur
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 2 581
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 36
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 2 581
Points : 6 013
Points : 6 013
Envoyer un message via Skype™ à rawsrc
Bonjour,

@stealth
Utiliser un champ Postgres ARRAY, voire un HSTORE n'est pas de la bidouille. Ce type de champ ont leur utilité crois-moi.

@cyscek
Pour formater ton ARRAY pour le sql, il te suffit d'utiliser l'échappement des string de Postgres sur chaque valeur et ensuite tu concatènes les valeurs échappées avec une virgule pour séparateur :

Allez cela donnerait quelque chose comme ça :
Code :
1
2
3
4
5
6
$delim = '$$';
$escaped = array();
foreach($data as $value) {
    $escaped[] = $delim.$value.$delim;
}
$sql = 'ARRAY['.implode(', ', $escaped).']';
La seule contrainte c'est de t'assurer qu'aucune valeur ne contiennent '$$', si tu en trouves, il te faudra définir un $delim qui n'est contenu dans aucune valeur.
Enfin, saches que le délimitateur de string est une des seule chose sensible à la casse sous Postgres.

Et n'oublies pas une chose essentielle : ne jamais utiliser PDO avec ce type de champ.
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 09h13.


 
 
 
 
Partenaires

Hébergement Web