filtre avec checkboxes

Mammouth du PHP | 643 Messages

24 juil. 2019, 10:13

Salut à tous, bon j'ai fait truc en PHP pour permettre de filter des résultats avec des checkboxes.

Le but étant de filtrer selon des options, parking, terasse et wifi

En bdd les valeurs son stocké en INT soit 1 si il y a l'option soit 0 si pas cette option.

Coté code j'ai fait des conditons avec pluiseurs else if mais je trouve ca un peu indigeste. ( je suis pour améliorer la chose, peut importe si on recharge la page ou pas)
$sql = $bdd->prepare("SELECT * FROM actu WHERE ville = :ville AND categorie = :categorie");
	$sql->bindParam(':ville', $_GET['ville'], PDO::PARAM_INT);
	$sql->bindParam(':categorie', $_GET['categorie'], PDO::PARAM_INT);
	$sql->execute();}

	// Terasse
	if (isset($_POST["terasse"])){
	  	$sql = $bdd->prepare("SELECT * FROM actu WHERE ville = :ville AND categorie = :categorie AND terasse = 1");
		$sql->bindParam(':ville', $_GET['ville'], PDO::PARAM_INT);
		$sql->bindParam(':categorie', $_GET['categorie'], PDO::PARAM_INT);
		$sql->execute();
	
	 }

	 // Parking
	else if (isset($_POST["wifi"])){
	  	$sql = $bdd->prepare("SELECT * FROM actu WHERE ville = :ville AND categorie = :categorie AND wifi = 1");
		$sql->bindParam(':ville', $_GET['ville'], PDO::PARAM_INT);
		$sql->bindParam(':categorie', $_GET['categorie'], PDO::PARAM_INT);
		$sql->execute();
	 }

	 // Wifi
	else if (isset($_POST["parking"])){
	  	$sql = $bdd->prepare("SELECT * FROM actu WHERE ville = :ville AND categorie = :categorie AND parking = 1");
		$sql->bindParam(':ville', $_GET['ville'], PDO::PARAM_INT);
		$sql->bindParam(':categorie', $_GET['categorie'], PDO::PARAM_INT);
		$sql->execute();
	 }

else if (isset($_POST["terasse"]) && isset($_POST["parking"]) && isset($_POST["wifi"])){
 	    $sql = $bdd->prepare("SELECT * FROM actu WHERE ville = :ville AND categorie = :categorie AND parking = 1 AND wifi = 1 AND terasse = 1");
		$sql->bindParam(':ville', $_GET['ville'], PDO::PARAM_INT);
		$sql->bindParam(':categorie', $_GET['categorie'], PDO::PARAM_INT);
		$sql->execute();
 }


Coté Filtre
<ul>	
								<form id="form" method="post" action="">
								<input type="checkbox" name="terasse" class="checkbox" <?=(isset($_POST['terasse'])?' checked':'')?>/> Terasse<br>
								<input type="checkbox" name="wifi" class="checkbox" <?=(isset($_POST['wifi'])?' checked':'')?>/> Wifi<br>
								<input type="checkbox" name="parking" class="checkbox" <?=(isset($_POST['parking'])?' checked':'')?>/> Parking<br>
								 </form>

								 <script type="text/javascript">  
								    $(function(){
								     $('.checkbox').on('change',function(){
								        $('#form').submit();
								        });
								    });
								</script>
								</ul>

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

24 juil. 2019, 11:58

Une autre approche serait de construire 1 seule requête SQL par morceau en fonction des paramètres reçus.
Un truc du genre :
$requete_sql = "SELECT * FROM actu WHERE ville = :ville AND categorie = :categorie";
if (isset($_POST['parking'])) $requete_sql .=" AND parking = 1";
if (isset($_POST['wifi'])) $requete_sql .=" AND wifi = 1";
if (isset($_POST['terasse'])) $requete_sql .=" AND terasse = 1";
$sql = $bdd->prepare($requete_sql );
Par ailleurs, je te recommande de filtrer en amont du traitement les données reçues avec la fonction filter_input_array() pour éviter les risques de sécurité :
https://www.php.net/filter_input_array

Et enfin, c'est mineur mais je préfère le signaler car ça peut devenir une source d'erreur assez fourbe : "terasse" s'écrit avec 2 "r". Tant qu'on fait la même faute partout ça ne pose pas de problème, mais je préfère le signaler car c'est le genre de coquille qui peuvent faire perdre du temps inutilement ;)
Quand tout le reste a échoué, lisez le mode d'emploi...

Mammouth du PHP | 643 Messages

24 juil. 2019, 14:54

merci pour "terrasse"

Par contre je ne vois pas de quoi tu veu me parler :

Par ailleurs, je te recommande de filtrer en amont du traitement les données reçues avec la fonction filter_input_array() pour éviter les risques de sécurité : ....

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

24 juil. 2019, 18:20

Par contre je ne vois pas de quoi tu veu me parler :

Par ailleurs, je te recommande de filtrer en amont du traitement les données reçues avec la fonction filter_input_array() pour éviter les risques de sécurité : ....
D'un point de vue de la sécurité, il est toujours préférable de filtrer toutes les variables que tu reçois d'un utilisateur afin de supprimer les caractères indésirables.
Par exemple, si quelqu'un tape en nom de ville "<script>alert('Coucou !');</script>", et que tu affoches dans le code de ta page le nom de la ville recherchée avec un simple echo $_GET['ville'], alors cela va provoquer l'affichage d'une popup.
Pour la popup ce n'est pas grave, mais cela peut être pire avec du vol de cookies ou de la redirection vers des sites de spam, etc...

Voici la liste des filtres disponibles par défaut dans PHP :
https://www.php.net/manual/fr/filter.fi ... nitize.php

Et tu peux appliquer ces filtres,
- soit variable par variable avec la fonction filter_var()
https://www.php.net/manual/fr/function.filter-var.php
- soit sur toutes les variables d'un tableau en même temps (par exemple $_GET ;-) ) avec filter_input_array()
https://www.php.net/manual/fr/function. ... -array.php
Quand tout le reste a échoué, lisez le mode d'emploi...

Mammouth du PHP | 643 Messages

25 juil. 2019, 09:50

Ok j'utilisé htmlspecialchars comme ci

htmlspecialchars(ucfirst(strtolower($_GET['ville'])))
Je vais regarder toutes tes doc, merci à toi

Mammouth du PHP | 643 Messages

25 juil. 2019, 15:45

Je vois que le fitre fait la même chose que htmlspecialcars par contre quel est le mieux, ? j'ai juste fait ça du coup:
if (!empty($_GET['ville'])) {
	$ville = htmlspecialchars(ucfirst(strtolower($_GET['ville'])));
}


Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

25 juil. 2019, 15:59

Le mieux c'est de filtrer au plus tôt donc dès la réception des données.
Car si c'est une données que tu enregistres en base, ça va t'enregistrer des tentatives de piratage et le jour où tu oublies un seul htmlspecialchars() à l'affichage tu te ferras avoir.
Quand tout le reste a échoué, lisez le mode d'emploi...