8768 sujets

Développement web côté serveur, CMS

Bonjour, Hello,

Voici en image la manière dont je souhaite filtrer mes produits.
L'utilisateur peut ajouter autant de filtres qu'il souhaite afin de trouver LA robe.

Tout va bien lorsque chaque colonne de ma table n'affiche qu'1 seule valeur (ex: catégorie = robes, ou couleur = noir), mais ça se complique lorsque la colonne contient plusieurs valeurs (ex : la robe est moitié en cuir / moitié en satin).
Si afficher ces données sur la page produit ne me pose pas de problème, en revanche j'ai du mal à filtrer mes produits en cochant la case satin si la robe est bi matière satin+ cuir.

Je ne sais pas faire ça avec FIND_IN_SET, c'est pour ça que j'ai opté pour LIKE (sur le 4e if isset) mais...



Ceci fonctionne nickel,

if (isset($_POST['action']))
   {  $where_terms = [];
      $params = [];
 
     $where_terms[] = "published = 'Yes'";		
     
    if ( isset ($_POST['product_category']))		   
       { $where_terms[] = 'FIND_IN_SET(p_cat_id,?)';
	  $params[] = implode(',',$_POST['product_category']);
	}	
    if ( isset ($_POST['product_brand']))
       { $where_terms[] = 'FIND_IN_SET(product_brand,?)';
	 $params[] = implode(',',$_POST['product_brand']);
           }

// mais ça ne fonctionne plus (ou pas) du côté du LIKE et du $where_2.
if ( isset ($_POST['product_material']))
   { $product_material = explode(',',$_POST['product_material']); 
     foreach ($product_material as $material_id)
	          { $search = "%$material_id%";
		    $where_terms_2[] = 'product_material LIKE ?';
		    $params[] = implode(',',$search);					  
		  }
  }    

    $where = '';
    if  ( !empty($where_terms))
        {  $where = 'WHERE ' . implode(' AND ',$where_terms);			  	
        	}  // Ca c'est Ok


  $where_2 = '';  // Ok ou pas ?
	if  ( !empty($where_terms) && !empty($where_terms_2))
     	    {  $where_2 =  implode(' AND ',$where_terms_2);			  	
	    }	
	 if ( empty($where_terms) && !empty($where_terms_2))
     	    {  $where_2 = 'WHERE ' . implode(' AND ',$where_terms_2);			  	
	    } 


$sql = "SELECT product_id, product_page, product_title, product_brand, product_price,  
             FROM products $where $where_2 ";  
             if (! $stmt = $pdo->prepare($sql)) {die(var_export($pdo->errorinfo(), TRUE));} ;
	 	$stmt->execute($params);


Merci pour la correction là où je fais faux. Smiley smile
upload/1604775257-51243-s.jpg
Modifié par Vape6 (08 Nov 2020 - 19:28)
Hello,

Ton approche n'est pas idéale sur le plan SQL.

Le minimum structurel c'est d'avoir trois tables, products, kv_components, components (voir image).

upload/1606760593-73933-capture.png

Du coup tu peu résoudre ta problématique avec un truc du genre (pas tester et rédigé à la volé) :

SELECT * FROM products AS P
INNER JOIN components AS C ON C.id_product = P.id 
INNER JOIN kv_components AS KVC ON KVC.id = C.id_component 
WHERE C.id_component IN (1,2,3,4)
GROUP BY P.id  


C.id_component IN (1,2,3,4) correspondant aux id de tes matériaux
Le group by permettant pour ne pas avoir de doublon dans les remontées.

NB :
Je ne pense pas me tromper en disant que ton code est perméable aux injections SQL. Un petit trim suivant d'un "preg_match" pour garantir le format des données arrivant des $_POST serait un minimum pour un site à visée commerciale.

Si tu sais pas comment faire : un petit tutoriel sur les requêtes préparées avec PDO et MySQL.
Modifié par gray_magic (30 Nov 2020 - 19:23)
Salut gray_magic Smiley cligne

C'est cool de me proposer des solutions & correctifs. J'apprécie bcp, c'est tellement rare & limité...........
Pour l'instant, j'ai supprimé la req qui me freinait, pour avancer, mais je retournerai sur ta proposition très bientôt Smiley lol et merci.

'Je ne pense pas me tromper en disant que ton code est perméable aux injections SQL. Un petit trim suivant d'un "preg_match" pour garantir le format des données arrivant des $_POST serait un minimum pour un site à visée commerciale."

Je ne sais pas du tout si "tu te casses la tête pour rien" ou si tu as parfaitement raison.
car sur les tuts américains de pdo ( https://phpdelusions.net/pdo , ils t'assurent que si tu passes un array en param, t'as pas besoin de préciser quoi que ce soit d'autre, car prepare ($stmt = $pdo->prepare($full_request); fait son job ?

Je ne sais pas à quel saint me vouer. phpdelusions me semble un site de référence, mais peut-être est-ce un leurre ? A mon niveau, jme pose des questions, je doute, mais à tort ou à raison ? Je ne suis pas capable de trancher...

Bon, going to bed, but I'll stay tunned Smiley smile Good to have friend or partners like u
Hi,
Les requêtes SQL préparées via PDO sont effectivement sécurisées, quand l'intégration est correcte (ce qui ici n'est pas le cas). La requête inclut aussi ses clauses WHERE que tu concatènes sans aucun contrôle. ce qui représente dans un audit une faille de sécurité.

Pour ta culture perso voici une intégration correcte qui utilise les marqueurs dans une clause WHERE : Tutoriel Français sur l'objet PDO.

Par ailleurs en sécurité informatique on applique toujours 3 principes :
1 : précaution (aucune confiance aux composants se comportant en boite noire, comme c'est le cas de PDO).
2 : contrôle, je n'utilise que ce que j'ai déjà contrôlé + sécurisé.
3 : je n'ai pas une vision absolue des possibilités et un tech en sait probablement plus que moi pour réaliser une attaque sur mon système, j'applique donc les 2 premiers points pour minimiser la surface d'attaque.

@+
Hi,

Merci. Je suis retournée sur le 1er lien que tu m'avais passé https://analyse-innovation-solution.fr/publication/fr/php/objet-pdo-et-securite-mysql
et 1. en tapant Clear_Front_Variable dans Google ( $Isbn = Clear_Front_Variable($_GET['isbn']);), je ne trouve aucun résultat.... ????? donc ils font un tut sur la sécurisation des vars, où ils donnent la moitié du procédé de sécurisation. lol super...

Je ne sais pas si tu parles anglais ou pas (mdr oui tu sais dire hi Smiley smile c'est déjà ça !), et j'avais posé la question sur le forum suivant https://www.sitepoint.com/community/t/products-filtering-options-through-mysqli-prepare/359115 (mais je cherchais comment avoir plusieurs Where IN avec mysqli prepare et non pas pdo > et on m'a convertie à pdo).

* Si tu comprends l'anglais et si t'as le temps, analyse la conversation, et le niveau d''expérience des personnes qui me répondent, et aussi les silences de ceux qui ne répondent plus. Qui a tort ? Qui a raison ? Est-ce que ceux qui ne disent plus rien ont tort ou raison ?

* Et 1ere réponse ça a été "FWIW, I wouldn’t do this with mysqli, because with PDO, you don’t have to bind parameters. You simply pass in an array of values when you execute.
C'est difficile de savoir si ces personnes répondent même si elles manquent de connaissances ou si au contraire, si elles te le disent, c'est que c'est des experts et que tu peux leur faire confiance.........

@+ Smiley smile
Modifié par Vape6 (02 Dec 2020 - 00:20)
Je pars sur un autre sujet : Es-tu à ton compte ou employé dans une entreprise de dev ?
Si 1 ou 2, quelles sont les garanties fournies avec le site ? Smiley smile
Comme une voiture (garantie 6 mois ou 7ans inviolable, incassable sinon réparations prises en charge)... Smiley smile
Hi !
Génération prémâchée +1 Smiley lol Clear_Front_Variable c'est clairement une variable custom du dev. Le sujet traite de la bonne utilisation de PDO pour s'éviter les injections SQL Smiley cligne pas de preg_match, ni de son petit frère diabolique que je suppose être utilisé correctement dans Clear_Front_Variable.

Le second point que tu soulèves est important, étant dans les deux cas (je suis lead dev full stack pour une boite qui à 5 sites de Ecommerce et j'ai mon auto entreprise en parallèle).
Tu es soumis à beaucoup, beaucoup,beaucoup de choses sur le plan légal.
Entre la RGPD et ta responsabilité de professionnel si la base de données tombe et que les données sont exfiltrées par négligence ou mauvaise pratique. Ou si la base de données est perdue genre tu perds 2 jours de commandes soit un CA de 20K va l'expliquer à tes clients ou à ton boss. Bonne chance même s’il est concilient Smiley smile ! Tu es clairement dans la m**** sur la plan juridique. Ta comparaison devrait plutôt être "je construis des voitures et... allé pas d'airbag parce que je ne sais pas faire" accident > 2 morts. "Ha?? Dommage".

Après je peu comprendre que tu doute des informations que tu lis ici et là et c'est une bonne chose mais contrôle TOUJOURS tes données qui proviennent du front, et celles qui proviennent de la base, c'est le BABA pour pas passer pour un kikoulol. Smiley biggrin
Hello Smiley smile Smiley smile

Clear_Front_Variable c'est clairement une variable custom du dev >> Oui,, mais ceci présenté sur un tuto n'a rien à y faire s'il n'est pas expliqué; et à 1ere lecture, j'ai pensé que ça aurait pu être une évolution dans la dernière version de php. Je ne vois pas pk PHP ou le SQL n'évolueraient pas et ne serait pas simplifiés au fur et à mesure que le temps avance, chaque année ou chaque 6 mois par exemple.
Sujet clos.

Génération prémâchée..

Je suis d'accord avec toi, mais pour ma part je suis fullstack 100% AUTODIDACTE donc prémâchée ????? Des lacunes je peux en avoir, même après 6ans d'exp, la preuve, mais du coup, je n'ai pas de prof ou potes etc à qui demander la meilleure façon de procéder dans telle ou telle circonstance. Je n'ai que Google, qui est un très bon allié, mais qui fait défaut dans pas mal de cas.

tu doute des informations que tu lis ici et là >>
Oui, c'est la 1ere chose que j'ai appris : "Never trust user input" Smiley smile et tkt j'ai pas oublié.
Mais si dans les cours que je trouve (en 4 langues), aucun n'est vraiment fiable, je fais comment pour deviner la meilleure solution ?
Modifié par Vape6 (06 Dec 2020 - 23:31)
Hey du coup ! Le meilleur moyen de se protéger d'une faille c'est de savoir l'exploiter. Comme ça, tu sais tester ta production, et tu sais exactement de quoi te protéger.

Les injections SQL - SQLi

Smiley pirate
Modifié par gray_magic (16 Dec 2020 - 11:53)