Hoe check ik of het emailadres of gebruikersnaam al aanwezig is bij handmatige invoer
Een nieuwe gebruiker kan zich op de site registreren. Dan wordt direct gecontroleerd en gemeld of de gebruikersnaam en emailadres al gebruikt worden. In de CRUD is dat weer een ander verhaal. Op het moment dat ik een nieuwe gebruiker/member aanmaak in de CRUD. Dan wil ik dat ook controleren. Dus fouten vermijden.
Mijn huidige code om de gegevens uit het formulier op te slaan staat hieronder:
Code (php)
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
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
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
?>
<?php
include('config.php');
if(isset($_POST['submit'])) {
$username=$_POST['username'];
$email=$_POST['email'];
$bedrijf=$_POST['bedrijf'];
$telefoon=$_POST['telefoon'];
$adres=$_POST['plaats'];
$naam=$_POST['naam'];
$wachtwoord=$_POST['wachtwoord'];
$active=$_POST['active'];
//hashed wachtwoord maken en straks opslaan
$wachtwoord=password_hash($wachtwoord, PASSWORD_BCRYPT);
//email validatie, code om email te testen. Vraag is of dit goed is qua opzet en aanroep.
//$email = htmlspecialchars_decode($_POST['email'], ENT_QUOTES);
//$stmt = $db->prepare('SELECT email FROM members WHERE email = :email');
//$stmt->execute(array(':email' => $email));
//$row = $stmt->fetch(PDO::FETCH_ASSOC);
//if(!empty($row['email'])){
// $error[] = 'Ingevoerd emailadres is al aanwezig.';
//}
$ad="insert into members(username,password,email,naam,bedrijf,adres,telefoon,active) values(?,?,?,?,?,?,?,?)";
$stmt= $mysqli->prepare($ad);
$stmt->bind_param("sssssssi",$username,$wachtwoord,$email,$naam,$bedrijf,$adres,$telefoon,$active);
$stmt->execute();
//$newId = $stmtins->insert_id;
$stmt->close();
echo "<script>alert('Gegevens zijn ingevoerd!');</script>" ;
}
?>
ini_set('display_errors', 'On');
error_reporting(E_ALL);
?>
<?php
include('config.php');
if(isset($_POST['submit'])) {
$username=$_POST['username'];
$email=$_POST['email'];
$bedrijf=$_POST['bedrijf'];
$telefoon=$_POST['telefoon'];
$adres=$_POST['plaats'];
$naam=$_POST['naam'];
$wachtwoord=$_POST['wachtwoord'];
$active=$_POST['active'];
//hashed wachtwoord maken en straks opslaan
$wachtwoord=password_hash($wachtwoord, PASSWORD_BCRYPT);
//email validatie, code om email te testen. Vraag is of dit goed is qua opzet en aanroep.
//$email = htmlspecialchars_decode($_POST['email'], ENT_QUOTES);
//$stmt = $db->prepare('SELECT email FROM members WHERE email = :email');
//$stmt->execute(array(':email' => $email));
//$row = $stmt->fetch(PDO::FETCH_ASSOC);
//if(!empty($row['email'])){
// $error[] = 'Ingevoerd emailadres is al aanwezig.';
//}
$ad="insert into members(username,password,email,naam,bedrijf,adres,telefoon,active) values(?,?,?,?,?,?,?,?)";
$stmt= $mysqli->prepare($ad);
$stmt->bind_param("sssssssi",$username,$wachtwoord,$email,$naam,$bedrijf,$adres,$telefoon,$active);
$stmt->execute();
//$newId = $stmtins->insert_id;
$stmt->close();
echo "<script>alert('Gegevens zijn ingevoerd!');</script>" ;
}
?>
Nu heb ik al een begin gemaakt met een controle op het emailadres. Wil dit graag even tegen de experts aanhouden. Dan wil ik ditzelfde bij de gebruikersnaam doen. Dus ik moet nog veel leren. En vandaar mijn vraag.
Wat adviseren jullie mij?
dank.
Jan
Maar je kan ook de records tellen die overeenkomen met het mailadres. Met rowCount() is dit eenvoudig te doen. http://php.net/manual/en/pdostatement.rowcount.php
Als je eerst gaat selecteren en dan gaat invoeren als het record niet aanwezig is zul je een lock moeten nemen op de tabel om te voorkomen dat er alsnog duplicaten ontstaan. Dat zal alles vertragen. UNIQUE is the way to go.
Dank! Pas ik direct toe.
function addUser()
{
if ($wachtwoord == $wachtwoord2) {
$db = connectDb();
$sql = "SELECT * FROM `gebruikers` WHERE eMail=:eMail";
$obj = $db->prepare($sql);
$obj->bindValue(":eMail", $eMail);
if($obj->execute() && $obj->rowCount() > 0) {
return "Email bestaat al ...";
}
else {
insert naar je database met alle benodigd geden, zoals email, wachtwoord, tel, account naam enz.
}
Gewijzigd op 30/03/2018 14:03:47 door - Ariën -
- Ariën - op 12/03/2018 12:34:49:
Ikzelf prefereer de methode om het veld in de database op UNIQUE inte stellen, en na het versturen te controleren op de errorcode.
Maar wat UNIQUE is hangt af van de collation (de sorteer- en vergelijkinstelling van de desbetreffende character encoding) van de database, tabel en/of kolom. Als de collation case-sensitive is, dan zijn de gebruikersnamen henk, Henk en HENK verschillend (uniek). Indien de collation case-insensitive is, dan zijn deze alle hetzelfde en zullen dan dus vanwege de UNIQUE constraint niet worden toegestaan.
Ben van Velzen op 12/03/2018 12:51:25:
Als je eerst gaat selecteren en dan gaat invoeren als het record niet aanwezig is zul je een lock moeten nemen op de tabel om te voorkomen dat er alsnog duplicaten ontstaan. Dat zal alles vertragen.
Maar dit is niet een operatie die om de halve seconde honderden keren wordt uitgevoerd maar gebeurt slechts af en toe: bij het toevoegen van een gebruiker, of bij het wijzigen van een profielgegevens. Tijdens de verwerking van die operaties is het prima toegestaan om tabellen tijdelijk te vergrendelen, al is het wat meer (programmeer)werk uiteraard. De vertraging lijkt mij dus niet een heel sterk argument gezien dit om te beginnen niet vaak voorkomt, en de vergrendeling zelf slechts een heel kort moment duurt (alleen tijdens de verwerking van een formulier).
Ben van Velzen op 12/03/2018 12:51:25:
UNIQUE is the way to go.
Maar dit alleen is ook niet genoeg. Je zou voor een gebruikersnamen ook eenduidige regels moeten vastleggen die aangeven hoe deze, naast het feit dat deze uniek moeten zijn, er uit dienen te zien. Zo zou je dus ook validatieregels voor een gebruikersnaam moeten hebben. En als je dan toch bezig bent is het tijdelijk vergrendelen van namen (en e-mailadressen) een kleine moeite.
En om antwoord te geven op de vraag (het topic): als je naam en/of e-mail wilt veranderen is het zaak dat je controleert of deze nieuwe waarden niet voorkomen in andere records. Dus zoiets:
Code (php)
1
2
3
4
2
3
4
SELECT COUNT(id) AS aantal
FROM usertabel
WHERE (email = [nieuwe_email] OR naam = [nieuwe_naam])
AND userid <> [id_van_huidige_user]
FROM usertabel
WHERE (email = [nieuwe_email] OR naam = [nieuwe_naam])
AND userid <> [id_van_huidige_user]
Deze query geeft altijd één resultaat terug met één waarde (in een kolom genaamd 'aantal'). Als de waarde van 'aantal' groter dan 0 is, dan zou dat inhouden dat je een dubbele gebruikersnaam of e-mailadres creëert (en als je dat dan toch probeert terwijl er UNIQUE constraints zijn op die kolommen dan zou dat dus een foutmelding opleveren).
En naast deze bovenstaande query, die je in een transactie zou moeten zetten (NB, je zult er ook voor moeten zorgen dat je DB transacties ondersteund worden en aan bovenstaande query moet dan tevens FOR UPDATE worden toegevoegd), zul je dus ook de gebruikersnaam en het e-mailadres moeten valideren met validatieregels voordat je het uberhaupt in de database probeert te stoppen.
NB: een e-mailadres is strict genomen slechts deels case-sensitive. Alleen het account-deel (het gedeelte voor de @) is in principe case-sensitive maar in de praktijk wordt vaak het hele e-mailadres als case-insensitive beschouwd.
Gewijzigd op 30/03/2018 21:25:05 door Thomas van den Heuvel