IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Comment avoir un WHERE avec plusieurs condition [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 102
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 102
    Points : 953
    Points
    953
    Par défaut Comment avoir un WHERE avec plusieurs condition
    Bonjour à tous,

    Je suis un peu frustrl car j'avais déjà fait ca, mais je n'arrive pas à retoruver ce vieux code grrrr.

    J'ai ce code
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    $sql_select = 'SELECT * FROM fields AS fi 
    	LEFT JOIN stations AS st ON fi.id_field = st.fields_id_field
    	LEFT JOIN sensors AS se ON st.id_station = se.stations_id_station
    	LEFT JOIN sensor_types AS stype ON se.sensor_types_id_sensor_type = stype.id_sensor_type
    	LEFT JOIN measures AS m ON se.id_sensor = m.sensors_id_sensor
    	LEFT JOIN collections AS c ON m.collections_id_collection = c.id_collection
    	WHERE st.id_station = '.$station.' AND c.collection_date >= "'.$from.'" AND c.collection_date <= "'.$to.'"
     
    	ORDER BY c.id_collection, c.collection_date ASC ';
     
    	$sql_result = $connect->query($sql_select);

    et je vais devoir ajouter ceci, au debut du fichier
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    	if(isset($_POST['wl'])){
    		$wl = $_POST['wl'];
    	}else{
    		$wl = ""; 
    	}
     
    	if(isset($_POST['wln'])){
    		$wln = $_POST['wln'];
    	}else{
    		$wln = ""; 
     
    	}
     
    	if(isset($_POST['hws'])){
    		$hws = $_POST['hws'];
    	}else{
    		$hfs = "";
    	}
     
    	if(isset($_POST['hwb'])){
    		$hwb = $_POST['hwb'];
    	}else{
    		$hfb = ""; 
    	}
     
    	if(isset($_POST['ta'])){
    		$ta = $_POST['ta'];
    	}else{
    		$ta = ""; 
    	}
     
    	if(isset($_POST['ts'])){
    		$ts = $_POST['ts'];
    	}else{
    		$ts = ""; 
    	}
     
    	if(isset($_POST['t30'])){
    		$t30 = $_POST['t30'];
    	}else{
    		$t30 = ""; 
    	}
     
    	if(isset($_POST['t60'])){
    		$t60 = $_POST['t60'];
    	}else{
    		$t60 = ""; 
    	}
     
    	if(isset($_POST['t100'])){
    		$t100 = $_POST['t100'];
    	}else{
    		$t100 = ""; 
    	}
     
    	if(isset($_POST['t200'])){
    		$t200 = $_POST['t200'];
    	}else{
    		$t200 = ""; 
    	}
     
    	if(isset($_POST['t500'])){
    		$t500 = $_POST['t500'];
    	}else{
    		$t500 = ""; 
    	}
     
    	if(isset($_POST['t1200'])){
    		$t1200 = $_POST['t1200'];
    	}else{
    		$t1200 = ""; 
    	}

    Donc ensuite, je vais devoir ajouter un nouveau critere de recherche et je vais devoir ajouté ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND stype.sensor_type_name = $wl
    mais pour chaqu'un (je ne l'ai liste pas tous.

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    WHERE st.id_station = '.$station.' AND c.collection_date >= "'.$from.'" AND c.collection_date <= "'.$to.'"
    AND (stype.sensor_type_name = $wl
    OR stype.sensor_type_name = $wln
    OR stype.sensor_type_name = $hfs
    OR stype.sensor_type_name = $hfb)

    Il y a pas une solution plus simple?
    Bien entendu, si $_POST['wl'] n'existe pas, $wl prend la valeur NULL car il ne doit pas extraire une valeru correspondant $ wl.

    Pourriez-vous me mettre sur la piste pour extraire les donnnées correspondant au $POST existant et qui ont une valeur?

    Milles mercis pour vos lumières!!

  2. #2
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 435
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 435
    Points : 15 807
    Points
    15 807
    Par défaut
    tout d'abord, il vaut mieux éviter de mettre directement des valeurs non vérifiées dans un requête.
    cela peut ouvrir la porte à des attaques par SQL injection
    https://securite.developpez.com/faq/...-SQL-Injection

    qu'utilisez vous pour vous connecter à la base de données ?

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AND (stype.sensor_type_name = $wl
    OR stype.sensor_type_name = $wln
    OR stype.sensor_type_name = $hfs
    OR stype.sensor_type_name = $hfb)
    s'écrit :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    AND ( stype.sensor_type_name IN ( $wl, $wln, $hfs, $hfb ) )

    Par contre, il est plus malin d'utiliser les id !

  4. #4
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 102
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 102
    Points : 953
    Points
    953
    Par défaut
    Hello!!!

    merci pour vos propositions

    @Matthieu.
    Merci pour cette observation.
    J'ai lu que magic_quote était depraciate. Il faudrait donc que j'ajoute des stripslashes

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $sql_select = 'SELECT * FROM fields AS fi 
    	LEFT JOIN stations AS st ON fi.id_field = st.fields_id_field
    	LEFT JOIN sensors AS se ON st.id_station = se.stations_id_station
    	LEFT JOIN sensor_types AS stype ON se.sensor_types_id_sensor_type = stype.id_sensor_type
    	LEFT JOIN measures AS m ON se.id_sensor = m.sensors_id_sensor
    	LEFT JOIN collections AS c ON m.collections_id_collection = c.id_collection
    	WHERE st.id_station = '.stripslashes($station).' AND c.collection_date >= "'.stripslashes($from).'" AND c.collection_date <= "'.stripslashes($to).'"
     
    	ORDER BY c.id_collection, c.collection_date ASC ';

    Mais je vais resté concentré sur ma requete des filtres pour le moment, je me concentrai la dessus, après

    @jreaux62
    Ca m'intéresse bien cette solution. Il faut savoir que j'ai des checkboxs et quand je sélection un ou plusieurs check box.
    Donc mon formulaire envoie ceci (ajax+POST)
    from=&to=&station=1&ts=1&ta=1&t30=1&t60=1&t100=1
    Donc les valeur que je récupère, ne sont pas de ID, mais des 1 ou des 0 (&t30=0). En fait, c'est des 1 (&t30=1), ou ...des riens, car si la checkbox t30 n'est pas checkée, il n'y pas le paramètre &t30, dans l'URL.

    Donc si je reste sur l'expéte &t30, je le récupère ainsi:

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // So existe et est egal à 1
    if(isset($_POST['t30']) && $_POST['t30']==1){
    		$t30 = "t30";
    	}else{
    		$t30 = "0"; 
    	}
    J'ai aussi une table qui liste mes capteurs et une table liée, qui liste le type de capteur.
    Dans la table 'sensor_type', j'ai un camps 'sensor_type_name' qui liste tous mes types de capteur:

    wl,
    wln,
    ta,
    ts,
    t30,
    t60,
    t120,
    ...etc
    Donc si je repreds ta proposition, et sachant que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $wl ="wl";
    $wln = "wln";
    $hfs ="hfs";
    $hfb = "hfb";
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $sql_select = 'SELECT * FROM fields AS fi 
    	LEFT JOIN stations AS st ON fi.id_field = st.fields_id_field
    	LEFT JOIN sensors AS se ON st.id_station = se.stations_id_station
    	LEFT JOIN sensor_types AS stype ON se.sensor_types_id_sensor_type = stype.id_sensor_type
    	LEFT JOIN measures AS m ON se.id_sensor = m.sensors_id_sensor
    	LEFT JOIN collections AS c ON m.collections_id_collection = c.id_collection
    	WHERE st.id_station = '.stripslashes($station).' 
            AND ( stype.sensor_type_name IN ( $wl, $wln, $hfs, $hfb ) ) 
            AND c.collection_date >= "'.stripslashes($from).'" AND c.collection_date <= "'.stripslashes($to).'"
     
    	ORDER BY c.id_collection, c.collection_date ASC ';
    On est d'accord qu'il va extraire les données liées
    • A la sattion 1 (pour autant que $station a la valeru de 1
    • Compris entre deux dates
    • les mesures dont sensor_type_name a les valeurs wl, wln, hfs, hfb

  5. #5
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 628
    Points
    3 628
    Billets dans le blog
    8
    Par défaut
    Ceci serait plus cohérent (et sans doute performant)
    Chaque filtre de chaque table doit être posé à la bonne jointure.
    Je te laisse tester.

    Par ailleurs, il faut que tu fasses remonter des champs de tes 6 tables ! sinon, tu ne pourras rien vérifier !
    Là, si j'ai bien compris, tu verras la même chose que si tu demandais :

    SELECT * FROM fields

    ahahah

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $sql_select = 'SELECT fi.machin,fi.truc,st.bidule,se.zigouigoui,stype.trucmuche,m.tata,se.toto,c.foo
    FROM fields fi 
    LEFT JOIN stations st ON fi.id_field = st.fields_id_field and st.id_station = '.stripslashes($station).' 
    LEFT JOIN sensors se ON st.id_station = se.stations_id_station
    LEFT JOIN sensor_types stype ON se.sensor_types_id_sensor_type = stype.id_sensor_type AND stype.sensor_type_name IN ( "'.$wl.'", "'.$wln.'", "'.$hfs.'", "'.$hfb.'" ) 
    LEFT JOIN measures m ON se.id_sensor = m.sensors_id_sensor
    LEFT JOIN collections c ON m.collections_id_collection = c.id_collection AND c.collection_date >= "'.stripslashes($from).'" AND c.collection_date <= "'.stripslashes($to).'"';

  6. #6
    Invité
    Invité(e)
    Par défaut
    ...les valeur que je récupère, ne sont pas de ID, mais des 1 ou des 0 (&t30=0)...
    Mauvaise méthode.

    Montre-nous :
    • le bout de formulaire avec les checkbox
    • la table sensor_type (comment tu l'as remplie)


    On peut faire plus simple que ton usine à gaz.

  7. #7
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 102
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 102
    Points : 953
    Points
    953
    Par défaut
    oh oui, c'est un peu une usine à gaz
    Je le post un peu plus tard, je suis entre deux feux...

  8. #8
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 244
    Points
    20 244
    Par défaut
    Comme cela à été dit ca serait plus judicieux d'utiliser des id que des labels pour tes filtres.
    C'est tout à fait faisable puisqu'on peut faire renvoyer ce que l'on veux à une checkbox :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <input type="checkbox" name="truc" value="123456" />
    Retournera 123456 si cochée.

    Ensuite , ce genre de chose:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if(isset($_POST['wl'])){
        $wl = $_POST['wl'];
    }else{
        $wl = ""; 
    }
     
    if(isset($_POST['wln'])){
        $wln = $_POST['wln'];
    }else{
        $wln = "";
    }
    peut être très largement simplifié par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $w1 = isset($_POST['wl']) ? $_POST['wl'] : "";
    $wln = isset($_POST['wln']) ?  $_POST['wln'] : "";
    Voir même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $w1 =  $_POST['wl']) ?? "";
    $wln = $_POST['wln'] ?? "";
    Si tu es en PHP 7 et +

    Note enfin, que utiliser des paramètres directement dans une requête est une faille de sécurité importante.
    Il faut soit traiter chaque paramètre individuellement , soit préparée les requêtes (solution plus simple qui évite tous les truc chiants du genre stripslashes).
    Voir http://php.net/manual/fr/pdo.prepared-statements.php et http://php.net/manual/fr/mysqli.quic...statements.php pour plus de détails

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bon. Comme grunk a (en partie) vendu la mêche , voici une bonne méthode de récupération :

    1- Pour les checkbox : on requête sur la table sensor_type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    // requete sur la table sensor_type
    // .....
    	foreach(....... as $row)
    	{
    ?>
      <input type="checkbox" name="sensor_type_ids[]" value="<?php echo $row['sensor_type_id']; ?>" /> <?php echo $row['sensor_type_name']; ?><br />
    <?php
    	}
    A noter :
    • name="sensor_type_ids[]" (avec des crochets)
    • value contient sensor_type_id (c'est là qu'est l'ASTUCE !)



    2- On récupère un array des cases cochées, contenant les sensor_type_id choisis !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $sensor_type_ids_array  = $_POST['sensor_type_ids']; // c'est un array
    3- on peut construire le bout de code qui va aller dans la requête : ".... IN (.......) " :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $sensor_type_ids_list = ( !empty($sensor_type_ids_array) )? implode( ',', $sensor_type_ids_array ); // on obtient : 1,14,15,...
    $clauseAND = "";
    if( !empty($sensor_type_ids_list) )
    {
       $clauseAND .= " AND stype.sensor_type_id IN (" . $sensor_type_ids_list . ") ";

  10. #10
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Citation Envoyé par pierrot10 Voir le message
    J'ai lu que magic_quote était depraciate. Il faudrait donc que j'ajoute des stripslashes
    Euh non, pas franchement. Tu n'as aucune raison d'avoir des slashes à retirer, vu que magic_quote ne les ajoute plus. Et stripslashes, addslashes et autres htmlspecialchars ne servent absolument pas à sécuriser les requêtes. C'est un peu comme dire que tu vas ajouter un rideau devant ta porte quand on te fait remarquer qu'il n'y a pas de serrure.

    Citation Envoyé par grunk Voir le message
    Note enfin, que utiliser des paramètres directement dans une requête est une faille de sécurité importante.
    Il faut soit traiter chaque paramètre individuellement , soit préparée les requêtes (solution plus simple qui évite tous les truc chiants du genre stripslashes).
    Voir http://php.net/manual/fr/pdo.prepared-statements.php et http://php.net/manual/fr/mysqli.quic...statements.php pour plus de détails
    Selon si tu utilises mysqli ou pdo, on peut adapter le code de jreaux pour y appliquer mysqli_real_escape_string ou construire une requête préparée

  11. #11
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 102
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 102
    Points : 953
    Points
    953
    Par défaut
    Vous êtes génial. Je regarde tout ca, ce soir

  12. #12
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 102
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 102
    Points : 953
    Points
    953
    Par défaut
    Helloo!!

    Merci pour vos conseils. J'ai donc suivi vos conseils mais je ne me suis pas encore attardé sur la sécurité.

    En partant de ce schéma et nommage (j'espère n'avoir pas laisser d'erreur)
    Nom : Screen Shot 2018-02-28 at 9.13.22 AM.png
Affichages : 1644
Taille : 205,3 Ko

    Le formulaire
    J'ai donc corrigé le formulaire pour qu'il envoit des ID et non plus des valeur. J'ai docn trois familles de check box: temperature, heatflux et water
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    <?php
    include_once("sql/db_config.inc.php");
    				include_once("sql/db_connect.inc.php");
    // $i me permet de faire trois bloques de famille
    	for($i=3; $i>0; $i--){
    		$sql_select = 'SELECT stype.id_sensor_type, stype.sensor_type_name, stype.sensor_type_longname, sfam.id_sensor_family, sfam.sensor_family_name FROM sensor_types AS stype
    		LEFT JOIN sensor_families AS sfam ON stype.sensor_families_id_sensor_family = sfam.id_sensor_family
    		WHERE sfam.id_sensor_family='.$i.'
    		ORDER BY sfam.sensor_family_name, stype.id_sensor_type ASC';
     
    	 	$sql_result = $connect->query($sql_select);
     
    		//echo "<h1>".$sql_result->num_rows." measures</h1>";
    ?>
    	<div class="checkbox">
    		<?php
    			while($row = $sql_result->fetch_assoc()){
    		//print_r($row);
    		?>
    				<div>
    					<input type="checkbox" data-name="<?php echo $row['sensor_family_name'] ?>" name="type[]" id="<?php echo "id-".$row['sensor_type_name'] ?>" value="<?php echo $row['id_sensor_type'] ?>" />
    					<label for="<?php echo "id-".$row['sensor_type_name'] ?>"><?php echo $row['sensor_type_longname'] ?></label>
    				</div>
    		<?php 
    			} 
    		?>
    	</div>
    	<?php
    	}	
    	include_once("sql/db_disconnect.inc.php");
    	?>
    ce qui donne
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    <div class="checkbox">
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-ta" value="5" />
    					<label for="id-ta">T-Air</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-ts" value="6" />
    					<label for="id-ts">T-Surface</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-t30mm" value="7" />
    					<label for="id-t30mm">T-30mm</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-t60mm" value="8" />
    					<label for="id-t60mm">T-60mm</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-t100mm" value="9" />
    					<label for="id-t100mm">T-100mm</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-t200mm" value="10" />
    					<label for="id-t200mm">T-200mm</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-t500mm" value="11" />
    					<label for="id-t500mm">T-500mm</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="temperature" name="type[]" id="id-t1200mm" value="12" />
    					<label for="id-t1200mm">T-1200mm</label>
    				</div>
    			</div>
    		<div class="checkbox">
    						<div>
    					<input type="checkbox" data-name="heatflux" name="type[]" id="id-hfs" value="3" />
    					<label for="id-hfs">Heatflux Shallow</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="heatflux" name="type[]" id="id-hfb" value="4" />
    					<label for="id-hfb">Heatflux Bottom</label>
    				</div>
    			</div>
    		<div class="checkbox">
    						<div>
    					<input type="checkbox" data-name="water" name="type[]" id="id-wl" value="1" />
    					<label for="id-wl">Waterlevel</label>
    				</div>
    						<div>
    					<input type="checkbox" data-name="water" name="type[]" id="id-wln" value="2" />
    					<label for="id-wln">Waterlevel normalized</label>
    				</div>
    			</div>
    Ce qui me semble propre!

    Récupération
    Maintenant dans mon ficher get_measure-v2.php, je récupère ainsi mes valeurs (je n'ai pas encore géré la sécurité).
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
            $station = isset($_POST['station']) ? $_POST['station'] : "1";
    	$from = isset($_POST['from']) ? $_POST['from']." 00:00:00" : "2017-10-22 00:00:00";
    	$to = isset($_POST['to']) ? $_POST['to']." 23:59:59" : "2017-10-23 23:59:59";
            $type_ids_array = isset($_POST['type']) ? $_POST['type'] : "";
    	//$type_ids_array = isset($_GET['type']) ? $_GET['type'] : ""; // FOR DEBUG
    	print_r($type_ids_array);
     
    	$type_ids_list = ( !empty($type_ids_array) ) ? implode( ',', $type_ids_array ) : ""; // on obtient : 1,14,15,...
    	$clauseAND = "";
    	if( !empty($type_ids_list) )
    	{
       		$clauseAND .= " AND stype.id_sensor_type IN (" . $type_ids_list . ") ";
       	}
    C'est en effet vraiment plus propre et allégé!!!

    Traitement
    Aussi, on a dit qu'il étatit préférable du filtrer les champs qu'on a besoin de récupérer.
    Donc j'ai supprimer ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM fields AS fi
    et j'ai spécifié les champs. Par contre là, la un peu plus compliqué mais c'est mieux car le script va uniquement traiter les champs qu'on a besoin...
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	$sql_select = 'SELECT fi.id_field,fi.field_name, st.fields_id_field, st.id_station,st.station_name, se.id_sensor, se.stations_id_station, se.sensor_types_id_sensor_type, stype.id_sensor_type, stype.sensor_type_name, m.value, m.sensors_id_sensor, c.id_collection,c.collection_date FROM fields AS fi 
    	LEFT JOIN stations AS st ON fi.id_field = st.fields_id_field
    	LEFT JOIN sensors AS se ON st.id_station = se.stations_id_station
    	LEFT JOIN sensor_types AS stype ON se.sensor_types_id_sensor_type = stype.id_sensor_type
    	LEFT JOIN measures AS m ON se.id_sensor = m.sensors_id_sensor
    	LEFT JOIN collections AS c ON m.collections_id_collection = c.id_collection
    	WHERE st.id_station = '.$station.' 
     
    	AND c.collection_date >= "'.$from.'" AND c.collection_date <= "'.$to.'"
    	'.$clauseAND.'
     
    	ORDER BY c.collection_date, c.id_collection, stype.id_sensor_type ASC ';

    Ca semble bien fonctionner et en plus, quand je ne sélectionne aucun type, ils m'affiche toutes les mesures.Quand je sélectionne certains types, il m'affiche que les mesures de ces types. Et ca c'est super.

    Question de sécurité
    (là, j'aurais encore besoin de votre aide)
    Donc là, ce que je voyais en suivant les commentaires de Celira, c'est d'utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysqli_real_escape_string
    En effet, dans mon fichier db_connect.php
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    include('sql/db_config.inc.php');
     
    	$connect = new mysqli($hote,$user,$password,$base) or die('Erreur de connexion '.mysql_error());
     
    	// Check connection
    	if (mysqli_connect_errno())
      	{
      		echo "Failed to connect to MySQL: " . mysqli_connect_error();
      	}
    j'utilise mysqli.

    Donc, si je reviens dans mon fichier get_measures-v2.php, je pensais le faire ainsi, avant le traitement, mais je ne suis pas convaincu:
    (je ne sais pas si je le fais au bon endroit)
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Si le $_POST existe alors.
    $station = isset($_POST['station']) ? $connect->real_escape_string($_POST['station']) : "1";
    	$from = isset($_POST['from']) ? $connect->real_escape_string($_POST['from'])." 00:00:00" : "2017-10-22 00:00:00";
    	$to = isset($_GET['to']) ? $connect->real_escape_string($_GET['to'])." 23:59:59" : "2017-10-23 23:59:59";

    Pour mon array, là, je peine car appremment mysqli_real_escape_string() ne peut pas être appliqué sur un array, n'est-ce pas?
    Attention: ci-dessous,j'utilise temporairemet un $_GET pour pouvoir tester directement avec mon url
    http://localhost:8888/chart/get_meas...station=1&type[]=7&type[]=8&type[]=10&type[]=11

    alors:
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
           //$type_ids_array = isset($_POST['type']) ? $_POST['type'] : "";
    	$type_ids_array = isset($_GET['type']) ? $_GET['type'] : ""; 
    	print_r($type_ids_array);
     
    	$type_ids_list = ( !empty($type_ids_array) ) ? implode( ',', $type_ids_array ) : ""; // on obtient : 1,14,15,...
    	$type_ids_list = $connect->real_escape_string($type_ids_list);
    Donc là, je n'ai pas d'erreur, mais si je change mon url avec un truc bison comme un \:
    http://localhost:8888/chart/get_meas...station=1&type[]=\r7&type[]=8&type[]=10&type[]=11

    là il m'ajoute un deuxième \ et mon debug m'affiche ceci
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    echo "<br>";
    	echo $type_ids_list;
    	echo $clauseAND;
    	echo "<hr>";
    Array ( [0] => \7 [1] => 8 [2] => 10 [3] => 11 )
    \\7,8,10,11 AND stype.id_sensor_type IN (\\7,8,10,11)
    et là, évidement ma requete MySQL plante!

    Donc maintenant, je ne vois pas trop comment bien sécurié mon formulaire

    J'ai essayé ceci avec un stripslashes(), qui semble résoudre mon problème

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $type_ids_list = $connect->real_escape_string(stripslashes($type_ids_list));
    mais je ne suis pas convaincu de bien faire.

    Que me suggeriez-vous encore pour bien protéger mon formulaire contre des intrusions.

    Milles mercis!!!!
    PS: J'espère avoir bien corrigé mon code et avoir été claire dans mes explications :o)

  13. #13
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Pour les champs simples, ce type de syntaxe $station = isset($_POST['station']) ? $connect->real_escape_string($_POST['station']) : "1"; est très bien

    Pour les tableaux, tu as deux possibilités : soit tu parcours le tableau à la main via un foreach pour appliquer real_escape_string à chaque valeur avant de l'utiliser, soit tu utilises une fonction comme array_​map pour le faire à ta place.

    Exemple en reprenant ton bout de code :
    Solution 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // on init avec un tableau vide si non renseigné
    $type_ids_array = isset($_GET['type']) ? $_GET['type'] : [];  
    print_r($type_ids_array);
     
    $type_ids_list = "";
    if (!empty($type_ids_array)) {
    	$escaped_type_ids_array = [];
    	foreach($type_ids_array as $type_id) {
    		$escaped_type_ids_array[] = $connect->real_escape_string($type_id);
    	}
    	$type_ids_list = implode( ',', $escaped_type_ids_array );
    }
    Solution 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // on init avec un tableau vide si non renseigné
    $type_ids_array = isset($_GET['type']) ? $_GET['type'] : [];  
    print_r($type_ids_array);
     
    $type_ids_list = "";
    if (!empty($type_ids_array)) {
    	$escaped_type_ids_array = array_map(array($connect, 'real_escape_string'), $type_ids_array);
    	$type_ids_list = implode( ',', $escaped_type_ids_array );
    }
    Personnellement, je trouve la 2e solution plus élégante, mais je pense que ça se vaut en termes de performances.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Si tu débutes (et n'a jamais utilisé myqsl_ avant) : OUBLIE mysqli_ !!!

    Et passe à PDO.
    Les requêtes préparées sont plus faciles à faire, et tu trouveras des tutos....

  15. #15
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 102
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 102
    Points : 953
    Points
    953
    Par défaut
    Salut jreaux62,
    Oui, je prends note de ceci, mais je dois rendre un résultat assez rapidement, et je ne veux pas maintenant prendre du temps à chercher comment le faire en pdo. Mais je le ferai. Le dernier truc que j'aimerais bien encore faire, si non je regarderai ca plus tard, c'est comment ajouter une couche de sécurité sur la récupération de mon formulaire.

    Mais la il faut vraiment que j'arrive à afficher mes charts. Je verrai ensuite comment optimiser mes traitements aved pdo, très volontier (surtout s'il y a des tuto), et surement que je repondrai au deux solutions à ce moment.

    C'est déjà super l'aide que vous m'avez donné!!!!!! Merci

  16. #16
    Invité
    Invité(e)
    Par défaut
    1- Une requête SQL BIEN préparée assure la sécurité de la bdd.

    2- Par contre, il faut en effet faire une gestion d'erreur en PHP des données reçues :
    • s'assurer que les données sont conformes (email, int, float...), pas vides (si obligatoires),...
    • strip_tags sur les input,....



    3- Pour l'affichage, htmlspecialchars() fait l'affaire.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Creer une clause WHERE avec deux conditions donne erreur
    Par Salsaboy60 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 15/04/2014, 11h39
  2. Réponses: 0
    Dernier message: 03/03/2011, 00h26
  3. Comment avoir un composant texte avec plusieurs styles?
    Par byubi dans le forum Composants
    Réponses: 1
    Dernier message: 02/05/2009, 13h12
  4. Réponses: 3
    Dernier message: 11/04/2008, 10h31
  5. Réponses: 10
    Dernier message: 26/03/2008, 16h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo