[RESOLU] question sur les requetes préparée

Mammouth du PHP | 506 Messages

19 mai 2021, 09:48

bonjour a tous
je souhaiterais faire des requêtes préparées mais il y a quelque chose que je comprends pas

c est le fameux district qui se transforme en $sistrict

dans l exemple de php

Code : Tout sélectionner

<?php $link = mysqli_connect("localhost", "my_user", "my_password", "world"); /* Vérification de la connexion */ if (mysqli_connect_errno()) { printf("Échec de la connexion : %s\n", mysqli_connect_error()); exit(); } $city = "Amersfoort"; /* Crée une requête préparée */ if ($stmt = mysqli_prepare($link, "SELECT District FROM City WHERE Name=?")) { /* Lecture des marqueurs */ mysqli_stmt_bind_param($stmt, "s", $city); /* Exécution de la requête */ mysqli_stmt_execute($stmt); /* Lecture des variables résultantes */ mysqli_stmt_bind_result($stmt, $district); /* Récupération des valeurs */ mysqli_stmt_fetch($stmt); printf("%s est dans le district de %s\n", $city, $district); /* Fermeture du traitement */ mysqli_stmt_close($stmt); }

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

19 mai 2021, 15:09

Hello !

Les requêtes préparées permettent de définir une structure SQL de base comportant des balises qui peuvent être remplacées dynamiquement par des valeurs pour enchainer les exécutions (et par exemple charger un grand nombre d'enregistrements dans une table en passant uniquement les valeurs de l'enregistrement suivant sans que le moteur n'ait besoin de procéder à la préparation de la requête à chaque fois).

Une requête préparée n'a en théorie aucun intérêt pour effectuer un select (s'il y a besoin d'exécuter un grand nombre de select consécutifs, c'est qu'il y a sans doute un problème de conception). Pour autant, elles ont un avantage et c'est ce qui pousse généralement les dev à s'en servir, c'est que les variables utilisées sont formatées et protégées par défaut lors de l'exécution.

On prépare donc une requête ainsi mysqli_prepare($link, "SELECT District FROM City WHERE Name=?"), sachant que le ? sera remplacé lors de l'exécution par la valeur "bindée", c'est à dire passée en paramètre lors de l'exécution. S'il s'agit d'une chaine de caractères, les apostrophes qui la délimitent seront ajoutés, et les caractères spéciaux éventuels qu'elle contient seront protégés.

L'instruction mysqli_stmt_bind_param($stmt, "s", $city), permet d'utiliser la valeur contenue dans la variable $city lors de l'exécution, en précisant qu'il s'agit d'un type string. Tu peux ensuite exécuter la requête et en récupérer le résultat afin de lire les enregistrements retournés.

Dans l'exemple ci-dessus, l'instruction mysqli_stmt_bind_result($stmt, $district); est utilisée afin de lier la variable $district au jeu de résultats de la requête. Sans cela, il n'y a aucun lien direct entre la variable $district et la colonne District de la table City. Mais tu pourrais tout aussi bien utiliser les méthodes fetch_assoc() ou fetch_row() pour récupérer les enregistrements et les parcourir :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 506 Messages

19 mai 2021, 16:24

bonjour Ryle
j adore tes explications
elles sont toujours bien claire et on comprends bien ce que tu expliques
déjà rien que pour ca merci

des fois , même souvent les exemples de php ne sont pas très claire

mais pourtant si on veux éviter une injection en mysql il faut protéger ce que l on entre dans notre base de donnée

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

19 mai 2021, 16:55

C'est tout l'intérêt d'un forum pour débutant et ce qui m'avais plus quand j'étais moi même arrivé ici : on aide pas juste à coder, mais à apprendre et à comprendre le php :)

Et oui, je te rejoins sur la clarté de certaines doc et exemples de php.net. C'est bien quand tu sais ce que tu cherches pour voir comment ça fonctionne, mais ça manque effectivement parfois d'explications ou de corrélations quand tu ne maîtrise pas le contexte ;)

Quant au fait de protéger les variables utilisées en SQL, c'est effectivement indispensable, mais on peut aussi les protéger sans nécessairement devoir utiliser de requête préparée. Pour une exécution unique, une requête préparée consommera plus de ressources qu'une requête classique. Ensuite c'est juste une question de contexte et le gain de temps passé à coder est souvent privilégié, la différence en terme de performance étant généralement négligeable.

C'est un peu comme enfoncer une vis avec un marteau, ca va fonctionner et c'est plus rapide, mais ce n'est pas à ça que servait le marteau à la base :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 506 Messages

19 mai 2021, 17:02

merci Tyle pour de nouveau ce beau chapitre d explication
et je te rejoins sur ce que tu viens d expliquer

c est en lissant un peu les forums que j ai pu m apercevoir qu il existait des failles de sécurité dans le php au niveaux des bases de données
et donc partout ou je suis alle voir , on parle de requête préparée, en fait dans mon cas c est un formulaire et donc comme l y a des champs ou l utilisateur peux entrer des données
y a une sonnette d alarme qui c est mise en route et donc cela fait deux jours que je planche sur ces requêtes préparées

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

20 mai 2021, 14:04

En fait, les requêtes préparées ne sont pas LA solution pour protéger son site des injections sql, et leur but principal est tout autre (améliorer les performances pour des traitements en masse), mais c'est effectivement UNE solution qui permet de protéger ses requêtes :)

Mais on est d'accord, il ne faut jamais faire confiance à tes utilisateurs et il est impératif de contrôler les données qu'ils envoient avant d'en faire quoi que ce soit ;)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 506 Messages

20 mai 2021, 15:57

bonjour Ryle
merci pour la réponse
mais alors comment protégés son site des injections sql ?

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

20 mai 2021, 23:01

En php on peut utiliser des méthodes du type mysql_real_escape_string() et consort, faire ses propres contrôles sur le format des données... Mais avec MySQL, les requêtes préparées restent la solution la plus simple pour protéger les données, surtout quand on débute :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 506 Messages

20 mai 2021, 23:18

ah ok Ryle
donc je vais en rester la
encore merci pour ton aide et surtout pour les explications