Champ "vide" pour variable lors d'une requète ?

Malouin
Invité n'ayant pas de compte PHPfrance

08 juil. 2008, 19:36

Salut,


je cherche à faire une requète mysql multicritères à partir de laquelle mes visiteurs pourraient trier les résultats selon leurs préférences. Pour ce faire, les variables sont postées à partir d'un formulaire où le visiteur sélectionne ses options ou non (à partir de listes dans le formulaire)

Le problème que je rencontre c'est lorsqu'un des critères n'est pas sélectionné : dans ce cas mysql lui attribue la valeur nulle et il n'y a donc aucun résultat.

Mysql lui attribue la valeur nulle car j'ai indiqué 'Value=""' dans mon formulaire.

Ce que je voudrais c'est que lorsque une des options n'est pas définie par l'utilisateur alors elle ne soit pas prise en compte ou autrement dit que la requète envoyée recherche uniquement les options qui ont été précisées par le visiteur.

Seulement je ne sais pas comment faire ca, y at-il une astuce pour qu'une variable envoyée par formulaire n'ait pas de valeur si elle n'est pas renseignée ?


J'ai réussi à contourner le problème en utilisant LIKE '$variable%' pour chaque variable mais je préfèrerais éviter car il me semble que ca présente des risques au niveau sécurité, comme par exemple avec l'injection de données dans l'url.

ViPHP
ViPHP | 5924 Messages

08 juil. 2008, 20:41

Il n'y a pas que si tu utilises un LIKE qu'il y a des problèmes de sécurité. Il faut absolument que tu échappes tes données entrantes avec mysql_real_escape_string() avant de les utiliser dans tes requètes.
Ensuite ce que tu demandes c'est de la programmation pure, c'est à dire que mysql n'est pas censé te faciliter la tache, il fait ce qu'il te dit, tu demandes des champs ayant pour valeur "", il les considèrera comme telles. C'est donc à toi de gérer ce comportement et de détecter dans les données entrantes si le champ en vide ou non, auquel cas tu ajoutes la condition à la requète ou tu ne l'ajoutes pas.
Par ailleurs, je te conseille plutôt de proposer une checkbox pour activer ou désactiver la condition, parce qu'avec ton système, l'utilisateur ne peut exiger qu'un champ soit vide…

Malouin
Invité n'ayant pas de compte PHPfrance

09 juil. 2008, 02:10

Oula :shock: ! Heureusement que tu es tombé sur mon message, je ne savais pas du tout cela.

- Est ce qu'il faut l'utiliser à chaque requète mysql (c'est à dire même lorsqu'on fait une requète à partir de variables déjà stockées dans la bdd) ou bien seulement lorsqu'on fait une requète à partir de variables provenant d'un formulaire ?


- Au lieu de :

Code : Tout sélectionner

$query = sprintf("SELECT * FROM users WHERE user LIKE 'xx%' AND password LIKE 'xx%' mysql_real_escape_string($user), mysql_real_escape_string($password));

il faut donc que je place simplement :

Code : Tout sélectionner

$query = sprintf("SELECT * FROM users WHERE user LIKE 'xx%' AND password LIKE 'xx%', mysql_real_escape_string($user), mysql_real_escape_string($password));
De cette facon ca fonctionne et c'est plus sécurisé, c'est bien ca ?



- En faisant ma recherche j'ai vu que quelqu'un préconisait d'utiliser en plus htmlspecialchars lors de la définition des variables avant la requète :

Code : Tout sélectionner

$variable = mysql_real_escape_string(htmlspecialchars($_POST['variable']));
C'est effectivement mieux ?

ViPHP
ViPHP | 5924 Messages

09 juil. 2008, 08:20

- Est ce qu'il faut l'utiliser à chaque requète mysql (c'est à dire même lorsqu'on fait une requète à partir de variables déjà stockées dans la bdd) ou bien seulement lorsqu'on fait une requète à partir de variables provenant d'un formulaire ?
Il faut le faire tout le temps…
- Au lieu de :

Code : Tout sélectionner

$query = sprintf("SELECT * FROM users WHERE user LIKE 'xx%' AND password LIKE 'xx%' mysql_real_escape_string($user), mysql_real_escape_string($password));

il faut donc que je place simplement :

Code : Tout sélectionner

$query = sprintf("SELECT * FROM users WHERE user LIKE 'xx%' AND password LIKE 'xx%', mysql_real_escape_string($user), mysql_real_escape_string($password));
De cette facon ca fonctionne et c'est plus sécurisé, c'est bien ca ?
T'as posté les deux mêmes codes :D
Mais c'est bien cela qu'il faut faire… :)

- En faisant ma recherche j'ai vu que quelqu'un préconisait d'utiliser en plus htmlspecialchars lors de la définition des variables avant la requète :

Code : Tout sélectionner

$variable = mysql_real_escape_string(htmlspecialchars($_POST['variable']));
C'est effectivement mieux ?
C'est n'importe quoi ce qu'il a dit, je t'explique pourquoi. htmlspecialchars() est une fonction qui permet de protéger des données avant l'affichage, cela entraine par ailleurs une altération des données. Mais dans une base de données, on stocke des données brutes, on ne les formate pas. Si jamais par exemple tu dois vérifier qu'un pseudo existe ou commence par un 'é', il est plus naturel de comparer les pseudos réels ou les pseudos formatés en html ?
Bref, le htmlspecialchars() (ou htmlentities() selon les goûts) se fait juste avant de les afficher, donc quand on les sélectionne, et non à l'insertion.

Malouin
Invité n'ayant pas de compte PHPfrance

19 juil. 2008, 00:48

Hum bon je suis un peu perdu. J'ai fait plusieurs recherches et essayé de mieux comprendre le fonctionnement de mysql_real_escape_string($variable) (manuel php, siteduzero, forums) mais je ne comprends pas tout.

D'après ce que j'ai compris cette fonction n'est utile que dans certains cas non : lorsqu'on récupère une variable via un formulaire ou qu'on passe les variables dans l'url ?


Si je fais une requète de ce style :
$sql = "SELECT article,lienint,lienext,prix,montant,description FROM articles WHERE prix>=300";
Ca sert à quelque chose (en supposant que chaque donnée est déjà renseignée dans la bdd) ?