Modifier plusieurs champs d'un tableau en même temps

Signaler
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010
-
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010
-
Bonjour,

Je suis débutant/bidouilleur en php/mysql

J'essaye de me faire ma propre gestion de mes comptes bancaires, et je bloque sur un truc.

J'importe le fichier csv des opérations bancaires, je formatte un tableau avec 8 colonnes, et je souhaite modifier certains champs sur ma page web.

Donc je me retrouve avec potentiellement plusieurs dizaines de champs modifiés lors de la même opération.

Comment coder ça en php/mysql ?

J'ai créé un formulaire en méthode = post, une boucle while récupère toutes les données de la base et les présente dans une table, et lorsque je clique sur le bouton 'modifier', j'envoie les données à une page modif.php.

Et c'est là que je bloque. Je sais mettre à jour une ligne dans une table, mais pas n lignes. J'imagine qu'il faut mettre une boucle mais je n'y arrive pas.

Faut-il utiliser un FOREACH ? (j'ai lu la doc, je comprends pas trop)

Comment est alors la structure ?

Comment être sûr que le formulaire envoie bien TOUTES les lignes et pas seulement la première par exemple ?

Merci de vos lumières.

13 réponses

Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010

une petite idée comme ça : serait-ce possible de faire ça :

<?php

$tableau1 = array ('colonne1', 'colonne2', 'colonne3', etc...);

$var = 'tableau1';
$nb_elements = count (${$var});
for ($i=0; $i<$nb_elements; $i++) {
$champ1=$_POST['champ1'];
$champ2=$_POST['champ2'];
etc...

et après la requête sql d'update ??

}
?>
Messages postés
164
Date d'inscription
samedi 16 octobre 2004
Statut
Membre
Dernière intervention
21 septembre 2010

salut!
si tu met ta requete UPDATE dans la boucle For normalement cela devrait fonctionner ! il fera un UPDATE pour chaque ligne de ton tableau.
Du coup ta requete sera :

"UPDATE TaTable SET ChampTable1 $champ1, ChampTable2 $champ2, ... WHERE IdentifiantLigne = Identifiant"

IdentifiantLigne est en fait la clé unique qui te permet d'identifier la ligne de ta Table à modifier. (Il faudra par exemple que tu aies cette valeur stockée dans ton tableau)

PS: Je t'ai donné la requête sans me soucier des guillemets...

[8)]Zoso
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010

OK j'ai compris. merci.

Dernière question :
effectivement j'ai bien un index pour chaque ligne, mais est-ce que ça suffit de mettre juste ça :
WHERE IdentifiantLigne = Identifiant
ou faut-il précédemment faire mention de cet identifiant dans la requête ? (l'initialiser ou autre chose)

merci pour ton aide
Messages postés
164
Date d'inscription
samedi 16 octobre 2004
Statut
Membre
Dernière intervention
21 septembre 2010

En fait il faut que tu mette :

WHERE IdentifiantLigne = $Identifiant

$Identifiant étant l'Id de la ligne que tu as récupéré dans la base en initialisant ton tableau.


[8)]Zoso
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010

Re-

Bon j'ai une erreur, j'ai trituré et essayé de comprendre mais que dalle.

voilà le code:

$tableau1 = array ('index', 'date_operation', 'montant', 'origine', 'numero', 'libelle_debit', 'libelle_credit', 'Categorie', 'paiement', 'rappro');

$var = 'tableau1';
$nb_elements = count (${$var});

for ($i=0; $i <= $nb_elements; $i++) {
$index=$_POST['index'];
$date_operation=$_POST['date_operation'];
$montant=$_POST['montant'];
$origine=$_POST['origine'];
$numero=$_POST['numero'];
$libelle_debit=$_POST['libelle_debit'];
$libelle_credit=$_POST['libelle_credit'];
$Categorie=$_POST['Categorie'];
$paiement=$_POST['paiement'];
$rappro=$_POST['rappro'];

$sql1 = "UPDATE perso_comptes SET date_operation= '$date_operation' , montant= '$montant' , origine= '$origine' , numero= '$numero' , libelle_debit= '$libelle_debit' , libelle_credit= '$libelle_credit' , Categorie= '$Categorie' , paiement= '$paiement' , rappro= '$rappro' WHERE index= $index";
$var1 = mysql_query($sql1) or die('Erreur SQL !
'.$sql1.'
'.mysql_error());
}

header('location: ./index.php');


et voilà l'erreur :
Erreur SQL !
UPDATE perso_comptes SET date_operation= '2010-02-17' , montant= '-1,8' , origine= 'Carte' , numero= '' , libelle_debit= ' CB REGIE PERIF.NORD 15/02/10 ' , libelle_credit= '' , Categorie= '' , paiement= '0' , rappro= '1' WHERE index= 163
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'index= 163' at line 1


Je précise que le nombre d'enregistrement aujourd'hui est bien de 163. Il a l'air de bloquer sur la dernière ligne, je ne sais pas pourquoi.

une idée?
Messages postés
3708
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
27 avril 2012
30
Salut,

Personnellement je n'ai rien compris à ta boucle. A quoi sert elle ?
A première vue à rien puisqu'elle ne fera que mettre à jour la même ligne 10 fois.

Si j'ai bien compris tu souhaites mettre à jour plusieurs lignes de ta base à partir d'un formulaire. Est ce bien cela ?

Si oui il faut boucler sur les lignes et non sur les champs.

Commence donc par mettre un print_r($_POST) tout en haut de ta page et informe nous du résultat. Montre également comment tu construis ton tableau HTML.

Par ailleurs pense à utiliser systématiquement mysql_real_escape_string() sur les données externes.

Cordialement,

Kohntark -
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010

bonjour,

Malgré plusieurs essais je n'y arrive pas.

Mon tableau html est le suivant :
<?php
echo '<FORM method="post" action="modif.php">';
echo '';
echo '	----
';
echo '		<center>Index</center>, <center>Date opération</center>, <center>Montant</center>, <center>Origine</center>, <center>N°</center>, <center>Libellé débit</center>, <center>Libellé crédit</center>, <center>Catégorie</center>, <center>Payé</center>, <center>Rappro?</center>, ';
echo '	';
while( $comptes = mysql_fetch_array( $requete ) )
{
echo '----
<center></center>, <center></center>, <center></center>, <center></center>, <center></center>, <center></center>, <center></center>, <center></center>, <center></center>, <center></center>, ';
}
echo '----
, ';
echo '
';
echo '</form>';
?>



ma page modif.php est la suivante :

<?php
print_r($_POST);

include("./include/connect.php");
include("./include/functions.php");

$index=$_POST['index'];
$date_operation=$_POST['date_operation'];
$montant=$_POST['montant'];
$origine=$_POST['origine'];
$numero=$_POST['numero'];
$libelle_debit=$_POST['libelle_debit'];
$libelle_credit=$_POST['libelle_credit'];
$Categorie=$_POST['Categorie'];
$paiement=$_POST['paiement'];
$rappro=$_POST['rappro'];

$tableau1 = array ('index', 'date_operation', 'montant', 'origine', 'numero', 'libelle_debit', 'libelle_credit', 'Categorie', 'paiement', 'rappro');

$var = 'tableau1';
$nb_elements = count (${$var});

for ($i=0; $i <= $nb_elements; $i++) {

$sql1 = "UPDATE perso_comptes SET date_operation='$date_operation' , montant= '$montant' , origine= '$origine' , numero= '$numero' , libelle_debit= '$libelle_debit' , libelle_credit= '$libelle_credit' , Categorie= '$Categorie' , paiement= '$paiement' , rappro= '$rappro' WHERE index= $index";
$var1 = mysql_query($sql1) or die('Erreur SQL !
'.$sql1.'
'.mysql_error());
}

//header('location: ./index.php');
?>


et au final j'ai toujours ce message :

Array ( [index] => 163 [date_operation] => 2010-02-17 [montant] => -1,8 [origine] => Carte [numero] => [libelle_debit] => CB REGIE PERIF.NORD 15/02/10 [libelle_credit] => [categorie] => [paiement] => 0 [rappro] => 1 ) Erreur SQL !

UPDATE perso_comptes SET date_operation='2010-02-17' , montant= '-1,8' , origine= 'Carte' , numero= '' , libelle_debit= ' CB REGIE PERIF.NORD 15/02/10 ' , libelle_credit= '' , Categorie= '' , paiement= '0' , rappro= '1' WHERE index= 163

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'index= 163' at line 1

Si quelqu'un a le temps de regarder 5mn, ça m'arrangerait et ça me ferait comprendre...

Merci
Messages postés
3708
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
27 avril 2012
30
Par ailleurs pense à utiliser systématiquement mysql_real_escape_string() sur les données externes.

=> Pourquoi ne tiens tu pas compte de cette remarque ?

A quoi sert elle ?

=> Re : A quoi sert elle ?

Si oui il faut boucler sur les lignes et non sur les champs.

=> Pourquoi ne tiens tu pas compte de cette remarque ?

Attention, index est un mot réservé mySQL, tu devrais renommer ce champ.


Kohntark -
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010

1/ Parce que je n'ai pas eu le temps de chercher de manière approfondie, et que les premiers éléments que j'ai réussi à comprendre de ça étaient pour protéger d'une injection SQL ?
Si c'est bien le cas, j'ai déjà protégé par htaccess le dossier général.

2/ Je souhaiterais, comme expliqué plus haut, mettre à jour plusieurs champs d'un tableau en même temps (en gros je modifie la catégorie des paiements pour pouvoir faire des stats par la suite)

3/ Parce que je ne l'ai pas comprise. Du moins j'ai supposé la comprendre, c'est pour ça que j'ai sorti les $_POST de la boucle, mais ça ne marche pas plus.

4/ C'est le nom du champ d'incrémentation dans la base. Ce n'est pas le but, de l'appeler index justement?
Messages postés
3708
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
27 avril 2012
30
Dommage que tu n'ai pas le temps de régler ton pb.
J'ai tout de même l'impression que tu prends un peu ce que tu veux dans les propositions qui te sont faites, c'est dommage et pas forcément agréable de parler dans le vide
Si il y a des points que tu ne comprends pas pourquoi ne pas le dire et demander plus d'infos ?

Enfin bref, revenons au sujet :
1/ mysql_real_escape_string() échappe les caractères qui pourraient poser pb dans une requête mySQL (', ", ...) Cela empêche une large partie des injections SQL, mais pas seulement.

Par exemple, tente d'entrer "c'est un test" dans le champ libelle_credit
Sans l'utilisation de mysql_real_escape_string tu vas te retrouver avec une belle erreur de syntaxe (à cause du ')
... tout est dans la doc

4/ index est un mot réservé par mySQL (comme group, date, where, etc ..), ce qui fait que tu ne peux pas l'utiliser comme nom de colonne, ou alors il faut l'entourer de ` mais ce n'est pas recommandé.

2/ 3/
Reprenons :
- tu as un tableau contenant plusieurs enregistrements (= lignes) possédants eux mêmes plusieurs champs (= colonnes)

> ta requête va mettre à jour tous les champs de l'enregistrement WHERE indentifiantxx

Pour mettre à jour ton tableau il faut donc que tu exécutes cette requête pour chaque enregistrement.

Hors ce que tu fais est de boucler sur les champs, pas sur les lignes !!

Pour y parvenir il faut déjà que les données de ton formulaire soient envoyées correctement afin de pouvoir les traiter correctement côté PHP.

Tu pourrais par exemple procéder ainsi :

while( $comptes = mysql_fetch_array( $requete ) )
   echo '<tr><td><center></center></td>
    <td><center></center></td>
    <td><center></center></td>
//[...]
}


Tu récupérerai comme cela un tableau id, date_operation, montant, ... dont chaque index correspond à 1 enregistrement :

$id[21] => id de l'enregistrement 21
$date_operation[21] = > date_operation de l'enregistrement 21
$montant[21] => montant enr n° 21

$id[22] => id de l'enregistrement 22
etc ...

Puis une simple boucle for pour lancer ta requête sur chaque enregistrement :
for ($i=0; $i < nb_tot_enr_tableau; $i++) {
   UPDATE perso_comptes SET date_operation=$date_operation[$i],
   montant = $montant[$i], ...
   WHERE id=$id[$i]
}


Cordialement,

Kohntark -
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010

Merci pour l'explication, je crois que j'ai compris.
En fait le fait de rajouter les [] envoie les données sous forme de tableau plutôt qu'une ligne, c'est ça ?

Pour ta première question, non je ne prends pas ce que je veux, j'essaye de creuser les choses avant d'embêter les gens, et comme je ne suis pas formé au développement, il se peut effectivement que je prenne pas les choses dans le bon ordre.
(En même temps si tu dis d'utiliser mysql_real_escape_string() sans donner plus d'explication, je pars du principe que t'as pas trop le temps d'en donner et donc je vais plutôt chercher ailleurs les raisons pour lesquelles tu mentionnes ça)


Dernière question avant d'essayer ce soir ce que tu proposes :
mysql_real_escape_string(), il faut le mettre dans quelle page ? celle où il y a le formulaire, ou celle, comme je le pense, où on reçoit les données et on fait l'update sql ?
Faut-il dans ce cas le mettre avant ou après le $_POST ?


Merci pour toutes tes précisions.
Messages postés
3708
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
27 avril 2012
30
En fait le fait de rajouter les [] envoie les données sous forme de tableau plutôt qu'une ligne, c'est ça ?

Oui, c'est ça.

Pour ta première question, non je ne prends pas ce que je veux, j'essaye de creuser les choses avant d'embêter les gens, et comme je ne suis pas formé au développement, il se peut effectivement que je prenne pas les choses dans le bon ordre.
(En même temps si tu dis d'utiliser mysql_real_escape_string() sans donner plus d'explication, je pars du principe que t'as pas trop le temps d'en donner et donc je vais plutôt chercher ailleurs les raisons pour lesquelles tu mentionnes ça)


C'est entendu. Dans ce cas désolé si ma réponse a pu te paraitre un peu "acide", mais comme beaucoup j'en ai marre des personnes qui pensent que tout leur est dû, qui ne prennent pas en compte les pistes qui leurs sont données, etc ... (et crois moi il y en a un paquet !)
Si je ne développe pas une préconisation, c'est d'une part que la doc est suffisamment bien faite (s'y référer doit être le premier réflexe) et d'autre part parce qu'il n'est pas toujours simple de juger le niveau d'une personne.
Ainsi je préfère grandement un "malgré la lecture de la doc je n'ai pas compris patati patata ..." plutôt que n'avoir aucune prise en compte et aucune question sur le sujet. Et je n'ai pas pour habitude de ne pas prendre le temps d'expliquer (en fonction de mes compétences of course) à des personnes qui respectent ces règles essentielles.
Bref.

mysql_real_escape_string(), il faut le mettre dans quelle page ? celle où il y a le formulaire, ou celle, comme je le pense, où on reçoit les données et on fait l'update sql ?
Faut-il dans ce cas le mettre avant ou après le $_POST ?

= > tu le penses bien
Les données externes provenant d'un formulaire (GET / POST) peuvent être source de nombreux pbs :
- tentatives d'attaques (injections SQL, ...)
- mais aussi erreurs de frappe, caractères spéciaux; entends pouvant poser pb dans la requête.
Réfère toi à la doc qui présente un exemple d'injection mySQL, qui reste valable pour une saisie "bien intentionnée" (cf l'exemple que je citais dans un autre post)

Ainsi :
J'entre "c'est un test" dans un champ de formulaire, que tu traites comme cela côté serveur :
<?php
$truc = $_POST['truc'];
$sql = "SELECT * FROM maTable WHERE bidule='$truc'";
if (false $query mysql_query($sql)) die(mysql_error());
?>


$sql va donner :
SELECT * FROM maTable WHERE bidule='c'est un test'

et hop : erreur de syntaxe car le moteur mysql va considérer que bidule='c' et verra est un test juste derrière, ce qui n'est pas syntaxiquement correct.

Avec mysql_real_escape_string :
<?php
$truc  = mysql_real_escape_string($_POST['truc']);
// [...]
?>


La requête sera :
SELECT * FROM maTable WHERE bidule=='c\'est un test'

Le caractère ' est échappé (\'), ce qui rend la requête valide.

Cela est indispensable si tu ne veux pas te retrouver avec des erreurs de ce type.
Même tarif pour les mots réservés mysql

Cordialement,

Kohntark -
Messages postés
20
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
1 mars 2010

Ok j'ai compris, merci.
Résultat des courses avec mysql_real_escape_string :
$date_operation= mysql_real_escape_string($_POST['date_operation']);

erreur suivante :
Warning: mysql_real_escape_string() expects parameter 1 to be string, array given in


En cherchant je vois que c'est normal car la page reçoit des tableaux et l'echappement se fait sur des strings.
J'ai trouvé cette fonction comme possibilité pour remédier au problème :
function recursive_escape(&$value) {
if (is_array($value))
array_map('recursive_escape', $value);
else
$value = mysql_real_escape_string($value);
}

et ensuite j'ai mis ça pour faire appel à la fonction :
$categorie= array_map('recursive_escape', $_POST['categorie']);


Maintenant je n'ai plus l'erreur string/array, mais j'ai toujours l'erreur du haut, et non plus sur la dernière ligne (163) mais sur la ligne 1 :
Erreur SQL !
UPDATE perso_comptes SET date_operation=, montant=, origine= , numero= , libelle_debit= , libelle_credit= , categorie= , paiement= , rappro= WHERE id=
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' montant=, origine= , numero= , libelle_debit= , libelle_credit= , categorie= , ' at line 1


est-ce que cette fonction pose souci ?

à noter que j'ai essayé un simple $categorie=array_map ('mysql_real_escape_string', $_POST['categorie']); mais j'avais toujours l'erreur qu'il s'attendait à un string