[RESOLU] Problème avec UPDATE

Avatar du membre
Eléphant du PHP | 88 Messages

23 févr. 2015, 16:54

Bonjour,
j'aurai besoin d'un peu d'aide SVP, car je suis débutant.

Je suis en train de créer une admin (petit CMS),
j'ai fait une page pour modifier mes articles, en haut j'ai une requête SELECT, ensuite dans les champs de mon formulaire j'ai mis :

Code : Tout sélectionner

value="<?php echo htmlspecialchars($modifier_article['title']); ?>
Jusqu'à là visiblement tout marche bien.

Ensuite en bas de ma page j'ai fait une requête UPDATE, et c'est la que j'ai un petit problème. Car par exemple avec ce code:

Code : Tout sélectionner

$db = Connexion(); $db->query("UPDATE articles SET title = '$title', contenu_article = '$contenu_article' WHERE id='6' ");
ça fonctionne uniquement pour l'article ayant l'id numéro 6, et je souhaiterai que ça fonctionne automatisent avec tout les article.

J'ai essayé ceci :

Code : Tout sélectionner

$db->query('UPDATE articles SET title = '.$title.', contenu_article = '.$contenu_article.'WHERE id="'.$_GET['id'].'" ');
Mais ça ne marche pas.

Comment faut-il faire ?
Merci beaucoup.

ViPHP
xTG
ViPHP | 7331 Messages

23 févr. 2015, 17:02

As-tu pensé à protéger tes variables contre les injections SQL avec la fonction quote() de PDO ?
Si ce n'est pas le cas je te le recommande vivement.

Enfin tu transmets des chaînes de caractères dans la requête, qui doivent être entourés de quotes en SQL. ;)
Tu le fais bien dans la première requête, mais dans la seconde tu as inversé les quotes et n'as pas reporté les quotes pour entourer $title et $contenu_article.

Avatar du membre
Eléphant du PHP | 88 Messages

23 févr. 2015, 17:17

As-tu pensé à protéger tes variables contre les injections SQL avec la fonction quote() de PDO ?
Si ce n'est pas le cas je te le recommande vivement.
OK merci,
Non je n'ai pas protégé avec la fonction quote()
je les est juste protégés comme ceci:

Code : Tout sélectionner

$title = mysql_real_escape_string(htmlspecialchars($_POST['title']));
Mais des fois wamp me dit que mysql_real_escape_string est obselete donc faudra que je trouve autre chose.
Enfin tu transmets des chaînes de caractères dans la requête, qui doivent être entourés de quotes en SQL. ;)
Tu le fais bien dans la première requête, mais dans la seconde tu as inversé les quotes et n'as pas reporté les quotes pour entourer $title et $contenu_article.
C'est quoi que t'apelle les quotes ? Car j'ai lu qu'avec les requete sql les simple-quotes(' ') et les doubles-quotes(" ") marchent.

Je comprend pas trop ce qu'il faut que je fasse pour résoudre mon problème.
Merci

Mammouth du PHP | 688 Messages

23 févr. 2015, 17:54

qu'est ce qu'affiche :
echo $_GET['id'];
dans la partie où se fait la requete d'update ?
car si le paramètre id est passé en POST et non en GET, cela n'affichera pas la donnée voulue.

Avatar du membre
Eléphant du PHP | 88 Messages

23 févr. 2015, 18:15

Ce que je veux, c'est une page modifier_article.php qui puisse servir à modifier tout mes articles.

J'ai une page afficher_articles.php (extrait de ce qu'y a dans cette page):

Code : Tout sélectionner

... <a href="../index.php?id=<?= $info_article['id']; ?> " target="_blank">Afficher</a> - <a href="modifier_article.php?id=<?= $info_article['id']; ?>">Modifier</a> - <a href="supprimer_article.php?id=<?= $info_article['id']; ?>">Supprimer</a>
et quand je clic sur "modifier", par exemple à coté de l'article ayant pour ID "6", je souhaite atterrir sur dans modifier_article.php sur cette page.

Donc j'ai ensuite mis ça en haut de ma page modifier_article.php :

Code : Tout sélectionner

<?php $db = Connexion(); $resultat = $db->query('SELECT * FROM articles WHERE id="'.$_GET['id'].'"'); $modifier_article = $resultat->fetch(); if(isset($modifier_article['id'])): ?>
Ensuite il y a le formulaire avec les input et un textarea pour modifier mes articles.
Jusqu'à la je pense que tout marche bien.

Et en bas de ma page modifier_article.php j'ai mis ça (c'est ici qu'est situé mon problème):

Code : Tout sélectionner

if(!empty($_POST['submit'])) { if(!empty($_POST['title']) AND !empty($_POST['description']) AND !empty($_POST['mots_cles']) AND !empty($_POST['titre_h1']) AND !empty($_POST['contenu_article'])) { $title = mysql_real_escape_string(htmlspecialchars($_POST['title'])); $description = mysql_real_escape_string(htmlspecialchars($_POST['description'])); $mots_cles = mysql_real_escape_string(htmlspecialchars($_POST['mots_cles'])); $titre_h1 = mysql_real_escape_string(htmlspecialchars($_POST['titre_h1'])); $contenu_article = mysql_real_escape_string(htmlspecialchars($_POST['contenu_article'])); $db = Connexion(); $db->query("UPDATE articles SET title = '$title', description = '$description', mots_cles = '$mots_cles', titre_h1 = '$titre_h1', contenu_article = '$contenu_article' WHERE id='6' "); echo 'La page a bien été modifié'; } else { echo '<p class="rouge bold">Tout les champs doivent obligatoires être remplis</p>'; } }
Avec ce code ça fonctionne que pour mon article ayant pour ID "6", ce qui est normal car j'ai mis: WHERE id='6'.
Au lieu de WHERE id='6' , qu'est ce qui faut mettre pour que ça fonctionne automatiquement pour chaque article?
J'ai éssayé de mettre ceci: WHERE id="'.$_GET['id'].'"
Mais ça ne marche pas.

ps: je suis débutant. ça fait plusieurs heures que je galère dessus.

Merci

ViPHP
xTG
ViPHP | 7331 Messages

23 févr. 2015, 18:37

1/ Tu utilises le driver (ou plutôt l'interface) PDO et donc il ne faut pas utiliser un autre driver en même temps (fonctions mysql_xxx)
2/ Pour faire ce que mysql_real_escape_string fait tu as la fonction quote avec PDO
3/ Il ne faut pas confondre les quotes de définition des chaînes de caractères PHP et les quotes de définition des chaînes de caractères SQL
$sql = "SELECT champs FROM maTable WHERE chaine='$variable'";
$sql = 'SELECT champs FROM maTable WHERE chaine=\'' . $variable .'\'';

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

23 févr. 2015, 18:44

Hello !

Première chose qui m'interpelle dans ton code, c'est l'utilisation des short tags pour afficher l'id dans tes liens. Ces derniers n'étant plus actifs par défaut dans les configurations de php, il est très fortement recommandé d'abandonner la syntaxe <? et <?= au profit de <?php et <?php echo pour que ton code ne dépende pas de la configuration du serveur à laquelle tu n'auras pas toujours accès.
...
<a href="../index.php?id=<?php echo $info_article['id']; ?> " target="_blank">Afficher</a> -
<a href="modifier_article.php?id=<?php echo $info_article['id']; ?>">Modifier</a> -
<a href="supprimer_article.php?id=<?php echo $info_article['id']; ?>">Supprimer</a>
Tu peux d'ors et déjà vérifier si cela change quelque chose dans l'url que tu ouvres en cliquant sur le lien, as-tu bien l'information index.php?id=6 ?

Pour tes requêtes SQL, il ne faut pas mettre des apostrophes ou des guillemets n'importe où. Seules les chaines de caractères (varchar, texte, date, ...) doivent être placées entre apostrophes (et pas entre guillemets, même si certains SGBD le tolèrent, ce n'est pas le cas de tous). Les nombres (int, tinyint, float, ...) ne doivent pas être délimitées (là encore si certains SGBD le tolèrent, ce n'est pas le cas de tous).

Pour construire ta requête commence par le résultat que tu souhaites obtenir :

Code : Tout sélectionner

UPDATE articles SET title = 'Mon Titre', contenu_article = 'Mon contenu ' WHERE id=6 -- Si on découpe la chaine pour extraire les données variables : "UPDATE articles SET title = '" . "Mon Titre" . "', contenu_article = '" . "Mon contenu" . "' WHERE id=" . 6 -- Tu peux maintenant inclure tes variables : "UPDATE articles SET title = '" . $title . "', contenu_article = '" . $contenu_article . "' WHERE id=" . $id
Nota : pour $id, tu dois effectivement récupérer la variable passée en get dans l'url, (en t'assurant au préalable qu'un id est bien passé dans l'url) il te faut donc :
if (isSet($_GET['id']))
   $id = $_GET['id'];
else
   $id = 0; // si tu veux gérer une valeur par défaut
Ce que l'on peut aussi écrire sous cette forme, ça revient au même :
$id = isSet($_GET['id']) ? $_GET['id'] : 0;
Ton script devrait déjà mieux fonctionner :)

Il faudra cependant faire ensuite attention à ce que l'on appelle les injections SQL et éviter que quelqu'un ne remplace la valeur ?id=6 dans l'url par ?id=6 or 1=1, ce qui aurait pour effet d'affecter toutes tes lignes et pas seulement celle qui a pour id 6... mais ça c'est une autre histoire ;)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Avatar du membre
Eléphant du PHP | 88 Messages

25 févr. 2015, 12:50

il est très fortement recommandé d'abandonner la syntaxe <? et <?= au profit de <?php et <?php echo pour que ton code ne dépende pas de la configuration du serveur à laquelle tu n'auras pas toujours accès.
...
<a href="../index.php?id=<?php echo $info_article['id']; ?> " target="_blank">Afficher</a> -
<a href="modifier_article.php?id=<?php echo $info_article['id']; ?>">Modifier</a> -
<a href="supprimer_article.php?id=<?php echo $info_article['id']; ?>">Supprimer</a>
Tu peux d'ors et déjà vérifier si cela change quelque chose dans l'url que tu ouvres en cliquant sur le lien, as-tu bien l'information index.php?id=6 ?
OK merci du conseils, c'est rectifié.
Et oui dans mes URL j'ai bien index.php?id=6 ? (d'ailleurs faudra que je vire par la suite les "?" et "=" des URL en trouvant un moyent que mes url soient toute ré-écrites automatiquement.).
Nota : pour $id, tu dois effectivement récupérer la variable passée en get dans l'url, (en t'assurant au préalable qu'un id est bien passé dans l'url) il te faut donc :
if (isSet($_GET['id']))
   $id = $_GET['id'];
else
   $id = 0; // si tu veux gérer une valeur par défaut
OK avec le code que tu m'a donné maintenant ça marche. J'ai aussi rajouté un intval il parait que ça aide à sécuriser.

Code : Tout sélectionner

if (isset($_GET['id'])) { $id_get = intval($_GET['id']); } else { header('location:erreur.php'); }
Il faudra cependant faire ensuite attention à ce que l'on appelle les injections SQL et éviter que quelqu'un ne remplace la valeur ?id=6 dans l'url par ?id=6 or 1=1, ce qui aurait pour effet d'affecter toutes tes lignes et pas seulement celle qui a pour id 6... mais ça c'est une autre histoire ;)
Merci de me l'avoir dit, mais je voit pas trop ce que tu appelle les injections SQL via le URL.
J'ai regardé ce que sont les injections SQL, j'ai vu que c'est pour éviter que des utilisateurs entre des caractères spéciaux (des simples quote je crois :' ' avec des mots clés comme OR) dans des champs input (qui vont aller dans une BDD). Mais j'ai rien trouvé en rapport avec les URL.

Merci à tous.