Page 1 sur 2
Eviter les doubles doublons
Posté : 27 mars 2007, 13:38
par lordbdp
J'ai actuellement une table simple avec :
id
nom
prenom
date
Mais je n'ai aucun système pour éviter d'avoir nom+prenom en doublon.
J'ai trouver cette ligne de commande mais comment faire pour que cela fonctionne sur 2 valeurs et non sur une seule car j'ai vu qu'on pouvait mettre un SELECT dans un autre SELECT mais j'ai arrive pas :
Code : Tout sélectionner
$test = mysql_query("SELECT * FROM donnees WHERE nom='$nom'");
$verdict = mysql_fetch_array($test, MYSQL_ASSOC);
if ($nom == $verdict['donneesnom'])
{ echo "Cette personne existe déjà dans la base de données<br>";
exit;
}
Merci d'avance.
Posté : 27 mars 2007, 15:47
par Ryle
Inutile de t'embêter avec une sous requête, il suffit d'ajouter un second paramètre dans ton WHERE
$sql = "SELECT count(*)
FROM donnees
WHERE nom='". $nom "'
AND prenom = '". $prenom ."'";
Posté : 27 mars 2007, 22:30
par AB
Bonjour,
Si besoin, voici le code de Ryle complété avec tes éléments:
$test = "SELECT count(*)
FROM donnees
WHERE nom='". $nom ."'
AND prenom = '". $prenom ."'";
$verdict = mysql_query($test, MYSQL_ASSOC);
$Total_row = mysql_fetch_row($verdict);
$total = $Total_row[0];
if ($total > 0)
{//personne déjà enregistée}
Mais attention car tel quel la requête n'est pas protégée des injections
Posté : 27 mars 2007, 23:03
par lordbdp
Merci pour le code manquant.
Comment faire pour se protéger des injections ? (C'est quoi une injection ???)
Merci encore.
Posté : 27 mars 2007, 23:27
par AB
Toute l'info dans les exemples de la fonction mysql_real_escape_string()
Selon la doc ta requête devrait ressembler à
$test = sprintf("SELECT count(*)
FROM donnees
WHERE nom='%s'
AND prenom ='%s'",mysql_real_escape_string($nom),
mysql_real_escape_string($prenom));
C'est important (pour éviter le piratage) si ce sont les visiteurs qui envoient leur nom et prénom via un formulaire.
Posté : 27 mars 2007, 23:52
par Ryle
Rien à ajouter si ce n'est juste une petite remarque pesonnelle concernant le sprintf... faut pas faire comme les éditeurs à la dreamweaver et l'utiliser pour des requêtes ... avec 2 paramètres c'est supportable (et encore) mais dès qu'il y en aura 5 ou plus, ca va vite devenir illisible.

On ne sait plus quelle variable va dans quel champ on perds du temps à vérifier l'ordre, les formats, c'est galère pour en rajouter un ou en enlever un... c'est sincèrement insuportable quand il faut passer derrière ce genre de code, alors qu'une simple concaténation donne le même résultat et est tellement plus simple à maintenir
$sql = "SELECT COUNT(*)
FROM donnees
WHERE nom = '".mysql_real_escape_string($nom)."'
AND prenom = '".mysql_real_escape_string($prenom)."'";
Il y a surement des fois où c'est utile (personnellement j'en ai pas encore trouvé, entre le cast implicite les fonctions de formatage) mais pitié, pas pour du sql
Vala, ca n'apporte rien de plus au sujet, c'était juste mon p'tit coup de trougne du soir

(faudrait d'ailleurs que je pense à l'ajouter au do's and don't sql çuilà

)
Posté : 28 mars 2007, 00:19
par AB
Salut Ryle,
Ben c'était pas du dreamweaver, c'était simplement le copié collé du premier exemple (1529) de la doc PHP sur mysql_real_escape_string()
Et comme je suis pas un expert, j'ai plutôt tendance à suivre la doc.
Maintenant si tu penses que ça ne sert à rien, ça m'arrangerais plutôt, car comme tu le dis, c'est assez pénible de passer derrière quand il y a beaucoup de paramètres...
Mais alors pourquoi la doc PHP conseille également le formatage dans l'exemple 1531. ça n'apporte strictement rien par rapport à une concaténation? même pas pour se protéger de pirates hyper tordus?
Posté : 28 mars 2007, 00:31
par Ryle
ah ben voilà ! tu as trouvé, ca sert dans la doc !
plus sérieusement, c'était pas du tout après toi ou dreamweaver (encore que pour ce dernier..

) mais justement parce que je comprend pas l'intérêt de cette fonction pour du SQL.
sprintf a pour but de formater une chaine.. alors c'est bien quand tu dois répéter plusieurs fois un élément, ca évite de le retaper à chaque fois (donc un seul endroit ou le modifier le cas échéant) et potentiellement inculquer la notion de type de données (même si ca n'empêche pas de continuer de voir des quotes autour de nombres

)
Mais pour générer du code sql, franchement, à part respecter la devise "ca a été dur à coder, ca doit être dur à comprendre" je vois vraiment pas

Posté : 28 mars 2007, 11:36
par lordbdp
Donc le code suiavnt serait le bon si j'ai bien compris :
Code : Tout sélectionner
$test = "SELECT count(*)
FROM donnees
WHERE nom='". $nom ."'
AND prenom = '". $prenom ."'";
$verdict = mysql_query($test, MYSQL_ASSOC);
$Total_row = mysql_fetch_row($verdict);
$total = $Total_row[0];
if ($total > 0)
{//personne déjà enregistée}
$test = sprintf("SELECT count(*)
FROM donnees
WHERE nom='%s'
AND prenom ='%s'",mysql_real_escape_string($nom),
mysql_real_escape_string($prenom));
Je ne rajoute pas un else avant le 2eme $test ?
Posté : 28 mars 2007, 11:53
par AB
La requête complète :
$test = sprintf("SELECT count(*)
FROM donnees
WHERE nom='%s'
AND prenom ='%s'",mysql_real_escape_string($nom),
mysql_real_escape_string($prenom));
$verdict = mysql_query($test, MYSQL_ASSOC);
$Total_row = mysql_fetch_row($verdict);
$total = $Total_row[0];
if ($total > 0)
{//le code que tu exécute si la personne est déjà enregistée
}
Mais bon, tu devrais aller faire un tour du coté de
http://www.phpdebutant.org et faire quelques tutos

sinon tu ne vas pas t'en sortir.
Posté : 28 mars 2007, 22:58
par lordbdp
Merci je vais tester. J'en profiterais pour aller jeter un oeil sur le site pour neuneus comme moi , lol.
Merci à tous.
Posté : 29 mars 2007, 08:09
par zeus
tu n'est pas "neuneu", juste débutant.
On est tous passé par là

Posté : 29 mars 2007, 18:14
par lordbdp
Ben je me prend un message d'erreur pour 2 lignes de code :
mysql_query(): supplied argument is not a valid MySQL-Link resource
pour :
mysql_fetch_row(): supplied argument is not a valid MySQL result resource
pour :
Je vous donne mon code complet si cela peut vous aider :
Code : Tout sélectionner
<title>Petition</title>
<style type="text/css">
body
{
background-color: white;
color: black;
font-family: Arial, Verdana, serif;
font-size: 12px;
}
input
{
border: 1px solid;
border-color: black;
background-color: white;
color: black;
font-family: Arial, Verdana, serif;
font-size: 12px;
}
table
{
border-collapse: collapse;
}
td
{
border: 1px solid;
border-color: black;
}
</style>
<?php
// On inclu le fichier de configuration
include('config.php');
?>
<form action="<?php echo $PHP_SELF; ?>" method="post">
<center>
Nous vous invitons à signer cette pétition, si vous le voulez bien, pour soutenir cette cause : <br /><br /><?php echo $cause; ?>
<br /><br /><br />
Prénom : <input type="text" name="prenom"><br /><br />Nom : <input type="text" name="nom">
<br /><br />Date : <?php echo date('d/m/Y'); ?>
<br /><br /><input type="submit" name="submit" value="Valider"> <input type="reset" name="reset" value="Recommencer">
<br /><br />
</center>
</form>
<?php
echo '<center><table><tr><td><b>Nom</b></td><td><b>Prénom</b></td><td><b>Date de signature</b></td></tr>';
// On se connecte à la base de données
mysql_connect("$host", "$login", "$password");
mysql_select_db("$bdd");
// On sécurise les champs
$nom = htmlspecialchars($_POST['nom']);
$prenom = htmlspecialchars($_POST['prenom']);
$date = date('d/m/Y');
$submit = htmlspecialchars($_POST['submit']);
// On vérifie que tous les champs sont bien remplis
if($submit && empty($nom))
{
// Message d'erreur
die('<center>Vous devez remplir tous les champs.<br /><br /></center>');
}
if($submit && empty($prenom))
{
// Message d'erreur
die('<center>Vous devez remplir tous les champs.<br /><br /></center>');
}
// On vérifie que les champs sont assez longs pour être raisonnables
$long1 = strlen($nom);
$long2 = strlen($prenom);
// Si le nom est trop court (plus petit que 3 caractères)
if($submit && $long1 < '3')
{
// Message d'erreur
die('<center>Votre nom doit faire plus de 3 caractères.<br /><br /></center>');
}
// Si le prénom est trop court (plus petit que 3 caractères)
if($submit && $long2 < '3')
{
// Message d'erreur
die('<center>Votre prénom doit faire plus de 3 caractères.<br /><br /></center>');
}
// On évite les doublons dans la base
$test = sprintf("SELECT count(*)
FROM petitions
WHERE nom='%s'
AND prenom ='%s'",mysql_real_escape_string($nom),
mysql_real_escape_string($prenom));
$verdict = mysql_query($test, MYSQL_ASSOC);
$Total_row = mysql_fetch_row($verdict);
$total = $Total_row[0];
if ($total > 0)
{
//Cette personne est déjà enregistée
die('<center>Cette personne a déjà signé la pétition.<br /><br /></center>');
}
if($submit)
{
// On enregistre la participation à la pétition
mysql_query("INSERT INTO power_petition VALUES('', '" . $nom . "', '" . $prenom . "', '". $date ."')");
}
// On sélectionne les résultats
$sql = mysql_query('SELECT * FROM power_petition ORDER BY id DESC');
// On compte le nombre de signatures
$signs = @mysql_num_rows($sql);
while($donnees = @mysql_fetch_array($sql))
{
?>
<tr>
<td>
<?php echo $donnees['nom']; ?>
</td>
<td>
<?php echo $donnees['prenom']; ?>
</td>
<td>
<?php echo $donnees['date']; ?>
</td>
</tr>
<?php
}
echo '</table></center>';
// On ferme la connexion MYSQL
mysql_close();
?>
Merci encore.
Si vous voulez voir le résultat :
http://www.neogame.fr/petitions/index.php
Posté : 30 mars 2007, 08:53
par orgerix
IL faut que tu mette MYSQL_ASSOC comme deuxième argument de mysql_fetch_array() et non de mysql_query().
(IL y a une fonction, mysql_fetch_assoc($requet) qui se comprote exactement comme mysql_fetch_array($requet,MYSQL_ASSOC))
Posté : 30 mars 2007, 16:05
par AB
Bonjour,
code à corriger en lieu et place de ta ligne existante :
$verdict = mysql_query($test);