8539 sujets

Développement web côté serveur, CMS

Bonsoir,

SELECT * FROM `pétitionnaires` WHERE mail = '$mail'


ne semble pas détecter la présence du mail dans la table pétitionnaires. Une idée ?
La question, posée autrement, est assez simple : Comment détecter la présence d'une valeur dans une colonne, et comment récupérer le résultat, en PHP ?
dagobert a écrit :
Bonsoir,

SELECT * FROM `pétitionnaires` WHERE mail = '$mail'


ne semble pas détecter la présence du mail dans la table pétitionnaires. Une idée ?


Bonjour il nous manque beaucoup d'informations pour répondre à cette question.

Comment est instancié la connexion à la bdd ? fonctionne t'elle correctement ?
Comment est fait l'execute de la requête sql en php ? comment la variable $mail est t-elle injecté ? comment est traiter le résultat ?
Modifié par JENCAL (15 Jun 2022 - 10:05)
Bonjour, JENCAL ! Et merci de t'intéresser à mon problème !!!

a écrit :
Comment est instancié la connexion à la bdd ?


define( "DB_SERVER", "sql313.hebergratuit.net" ) ;
define( "DB_USER", "heber_31275822" ) ;
define( "DB_PAWO", "x" ) ;
define( "DB_NOM", "heber_31275822_Rebel" ) ;

$db_connex = new mysqli( DB_SERVER, DB_USER, DB_PAWO, DB_NOM ) ; 


a écrit :
fonctionne t'elle correctement ?

Oui !

a écrit :
Comment est fait l'execute de la requête sql en php ?


$query = "SELECT * FROM `pétitionnaires` WHERE mail = 'x@x.x'" ;
$result = mysqli_query( $db_connex, $query ) ;


a écrit :
comment est traiter le résultat ?

C'est l'objet de ma question !!!

Merci de ton aide !
Salut,

SELECT * FROM `pétitionnaires` WHERE mail = 'x@x.x'

D'un point de vue mysql, ta requête semble correct

Par contre une fois que tu passes en php, il faut éviter de mettre directement les paramètres php dans ta requête pour eviter les injections sql.
A la place il faut plutôt utiliser les systèmes de requêtes préparées : https://www.php.net/manual/fr/mysqli.prepare.php (Et pour que tu regardes les bonnes parties de code : tu utilises le style procédurale, pas le style objet (je précise histoire de t’éviter de faire des mix bizarres)

Et après il faudrait nous dire ce que tu obtiens comme résultat exactement.
Ok,

Suis bien les conseils de mathieu, pour éviter les injections sql. ensuite tu pourras faire comme cela

 $query = "SELECT * FROM `pétitionnaires` WHERE mail = 'x@x.x'" ; // à refaire pour éviter les injections sql
 $results= mysqli_query($conn, $query );

 while ($row = mysqli_fetch_assoc($results))
 {
    echo $row['email'];
 }

Modifié par JENCAL (15 Jun 2022 - 14:51)
Bonsoir,

et merci de vos contributions !

Je vous remercie de me sensibiliser à la question de la sécurité.

Dans un premier temps, voilà de quoi il s'agit : mon commanditaire souhaite organiser une pétition. Le formulaire est http://labo.hebergratuit.net/Rebel/?petition-form J'ai choisi d'identifier les pétitionnaires par leur mail (oui, je sais, nombreuses sont les personnes qui ont plusieurs mails, mais cela me semble la moins mauvaise solution, non ?). Au moins souhaité-je empêcher la soumission multiple du même mail.

C'est pourquoi je veux vérifier que le mail proposé n'est pas, déjà, enregistré dans la base. D'où :

$query = "SELECT * FROM `pétitionnaires` WHERE mail = '$mail'" ;
$result = mysqli_query( $db_connex, $query ) ;

Sauf que je ne comprends pas comment récupérer la réponse :o( ???

Eurêka ! Je teste mysqli_num_rows( $result ) !!!

<?php

error_reporting( E_ALL ) ; session_start() ; include "Data/database-init.php" ; 

$_SESSION["pétition"] = $_POST ;
$_SESSION["pétition"]["time"] = time() ;
$_SESSION["pétition"]["token"] = $_SERVER["QUERY_STRING"] ;
  
$mail = $_POST["mail"] ;
$query = "SELECT * FROM `pétitionnaires` WHERE mail = '$mail'" ;
$result = mysqli_query( $db_connex, $query ) ;
 
if( mysqli_num_rows( $result ) )
{
$style = "background:#fff; display:inline-block; margin-top:1ex;" ; 
$bouton = "<br /><a class=\"boutons\" style=\"$style\" href=\"?participer-financement\">Oui, bien sûr !!!</a>" ; 
die( "Vous avez déjà signé la pétition ! Merci !! Souhaitez-vous participer au financement de l'opération ?$bouton" ) ;
}

?>


Me reste à réfléchir à la question de la sécurité.

Question subsidiaire : Comment récupérer, le plus directement, le nombre de lignes d'une table ?

Merci de votre soutien ! Je vous souhaite une bonne soirée.
Vous me suggérez de sécuriser les entrées dans la base : bien.

Mais, il me semble qu'il existait, autrefois, une fonction php qui permettait de vérifier l'innocuité des entrées de formulaire; vous dit-ce quelque chose ?
Il existe la fonction filter_input() pour vérifier les infos provenant de $_GET ou $_POST. Il y a de nombreux filtres à combiner avec cette fonction, tu peux par exemple vérifier et valider des infos ou les nettoyer par exemple.

Même si le paramètre filter de cette fonction est optionnel, il faut indiquer un filtre, car sinon le filtre par défaut n'a... aucun effet ^^
Merci, Logara, d'avoir signalé l'existence de cette fonction !

Pour protéger, finalement, la base de données, j'utilise mysqli_real_escape_string. Pour info :

<?php // mail2daba.php

error_reporting( E_ALL ) ; session_start();
 
if( $_SESSION["pétition"] )
{
$_SESSION["pétition"]["time"] = $_SESSION["pétition"]["time"] ?? 0 ;
$_SESSION["pétition"]["token"] = $_SESSION["pétition"]["token"] ?? sha1(rand()) ;

$nunc = time() ;
$_SESSION["pétition"]["ok-time"] = $nunc - $_SESSION["pétition"]["time"] < 600 ;
$_SESSION["pétition"]["ok-token"] = $_SESSION["pétition"]["token"] == $_SERVER["QUERY_STRING"] ;
$_SESSION["pétition"]["ok-all"] = $_SESSION["pétition"]["ok-time"] && $_SESSION["pétition"]["ok-token"] ;

if( $_SESSION["pétition"]["ok-all"] )
{
include "Data/constantes.php" ;
include "Data/database-init.php" ; 

date_default_timezone_set( "Europe/Paris" ) ;
$dis = array( "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche" ) ;
$_SESSION["pétition"]["horodatage"] = $dis[date("N", $nunc )-1].SPACE.date( "y/m/d G:i:s", $nunc ) ;

$hnoms = array( "nom", "prénom", "mail", "horodatage" ) ;
foreach( $hnoms as $hnom ) $values[$hnom] = mysqli_real_escape_string( $db_connex, $_SESSION["pétition"][$hnom] ) ; 

$headersline = BAX.implode( BAX.VI.BAX, $hnoms ).BAX ;
$valuesline = APOS.implode( APOS.VI.APOS, $values ).APOS ;
$query = "INSERT INTO `pétitionnaires` ( $headersline ) VALUES( $valuesline )" ;
mysqli_query( $db_connex, $query ) ; 
if( mysqli_error( $db_connex ) ) die( mysqli_error( $db_connex ) ) ;
}
}

header( "Location: rebel.htmlroot?retour-petition" ) ;

?>
Salut,

pour ta page de formulaire tu as mis :
<input type="email" name="mail" placeholder="contact@mfrbmontreuil.info" pattern="^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$">

Je ne sais pas comment cela à évolué depuis le temps, mais il me semble qu'il fallait soit mettre le type email soit le pattern mais pas les 2 pour éviter une double vérification du navigateur (ce qui pouvait entraîner des bugs sur certains navigateurs).

Ensuite pour revenir à ton problème, à savoir éviter les doublons d'adresse mail, de mon point de vue la solution simple serait de rajouter une contrainte d'unicité sur la colonne mail dans la base de données.

Au moment de la création de la table tu peux préciser UNIQUE sur une colonne pour indiquer que cette colonne ne peut pas avoir de doublon ( ce qui correspond à ton cas a priori).
Vu qu'a priori la table existe déjà il faudra faire un alter table :

ALTER TABLE pétitionnaires
ADD CONSTRAINT mail_unique 
UNIQUE (mail);

Par contre pour que la contrainte puisse s'appliquer il faut que la table ne contiennent pas de ligne avec un doublon sur l'email (il faudra nettoyer la table en les supprimant/corrigeant pour pouvoir appliquer l'ajout de la contrainte)
Modifié par Mathieuu (16 Jun 2022 - 11:18)
JENCAL a écrit :
tu as la fonction num_row

Il existe, en mysql, COUNT(*); mais je ne comprends pas comment l'exploiter intelligemment.

Du coup, en attendant de comprendre comment utiliser COUNT(*), intelligemment, j'adopte une solution similaire à celle de JENCAL :

$query = "SELECT * FROM `pétitionnaires`" ;
$result = mysqli_query( $db_connex, $query ) ; 
$size = mysqli_num_rows( $result ) ;


Mathieuu a écrit :
Je ne sais pas comment cela à évolué depuis le temps, mais il me semble qu'il fallait soit mettre le type email soit le pattern mais pas les 2 pour éviter une double vérification du navigateur (ce qui pouvait entraîner des bugs sur certains navigateurs).

Merci de me sensibiliser à cette problématique. Je vais réfléchir.

Mathieuu a écrit :
Ensuite pour revenir à ton problème, à savoir éviter les doublons d'adresse mail, de mon point de vue la solution simple serait de rajouter une contrainte d'unicité sur la colonne mail dans la base de données.

Mon parti, c'est de tester l'unicité, avant de compléter la table :

$query = "SELECT * FROM `pétitionnaires` WHERE mail = '$mail'" ;
$result = mysqli_query( $db_connex, $query ) ;
if( mysqli_num_rows( $result ) ) // le mail existe, déjà, dans la table ;


Bon après-midi, à tous !!!
dagobert a écrit :

Il existe, en mysql, COUNT(*); mais je ne comprends pas comment l'exploiter intelligemment.

Du coup, en attendant de comprendre comment utiliser COUNT(*), intelligemment, j'adopte une solution similaire à celle de JENCAL :

$query = "SELECT * FROM `pétitionnaires`" ;
$result = mysqli_query( $db_connex, $query ) ; 
$size = mysqli_num_rows( $result ) ;



Si tu veux utilise les COUNT sur ta requêtes sql mais que tu veux également connaitre les résultats il faut passer par mysqli_num_rows qui va faire le COUNT pour toi.

après je ne comprend pas le "Exploiter intelligemment" le count?
Modifié par JENCAL (16 Jun 2022 - 15:51)
Bonjour !

Ce qui serait élégant, ce serait de pouvoir récupérer le nombre de lignes d'une table, sans passer par SELECT; mais, par exemple, directement, avec COUNT.

Or, si on utilise COUNT, tout seul, mysqli_num_rows renvoie 1, ce qui n'est pas la réponse recherchée.

Je suis preneur d'une solution !!!
dagobert a écrit :
Bonjour !

Ce qui serait élégant, ce serait de pouvoir récupérer le nombre de lignes d'une table, sans passer par SELECT; mais, par exemple, directement, avec COUNT.


un COUNT sql est forcément utilisé avec SELECT. Si tu parles d'un count() php c'est différents et tu peux le faire sur n'importe quel array php.
tu peux faire un SELECT COUNT(*) FROM ma_table
et oui cela te renvoi qu'une seul ligne avec pour résultat le comptage total.

Tu es obliger de faire un "SELECT" d'une table pour compter les résultats. tu es obliger de faire une requête SQL pour avoir des infos "sql"


dagobert a écrit :

Or, si on utilise COUNT, tout seul, mysqli_num_rows renvoie 1, ce qui n'est pas la réponse recherchée.

Je suis preneur d'une solution !!!


Oui si tu utilises un mysqli num rows sur une requête sql SELECT COUNT(*) cela sera égale à 1. Oui cela te renvoi qu'une seul ligne avec pour résultat le comptage total.
Faire un mysqli_num_rows sur un SELECT COUNT() n'a pas de sens.
Modifié par JENCAL (17 Jun 2022 - 11:38)