• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Duplicate entry for key...

Tobi44

Mitglied
Moin,

habe nun ein kleines "Kontaktformular" gebastelt, welches mir die Usereingaben per Mail schickt und auch in der DB speichert.

Funzt soweit, Problem ist, dass ich die Daten in der DB nur speichere um das mehrfache Absenden einer Mail mit der gleichen E-Mail Adresse verbieten möchte. Habe die Spalte email in der DB unique, damit beim Posten der Eintrag nur einmal geschieht. Wenn man nun über die Website eine Mail erneut mit der gleichen E-Mail Adresse verschickt, kommt die Meldung dass die Mailadresse bereits in Verwendung ist.

Wenn ich nun aber die Mailadresse nicht 1:1 eingebe, wie sie in der DB steht, bspw statt [email protected] (so in der DB) [email protected] (so die Usereingabe) kommt nicht die Fehlermeldung des Scriptes (Mailadresse bereits in Verwendung), sondern "Duplicate entry '[email protected]' for key 2". Kann ich evtl. in die insert into dings was reinstecken, sowas wie if not exists, was prüft ob das Feld email nicht schon in der DB existiert? Dann könnte ich das mit dem unique in der Spalte wieder weg machen.

Gruß
 
Hallo,

das hilft mir nicht viel weiter.

Das Problem liegt wohl darin, dass die Mailadressen, die in der DB stehen, genauso eingegeben werden müssen vom User im Formular, wie sie in der DB stehen, wenn zB ein Buchstabe groß statt klein geschrieben wird, kommt die Fehlermeldung*Duplicate entry '[email protected]' for key 2. Wenn die Mailadresse in der gleichen Groß- und Kleinschreibung vom User eingegeben wird wie sie in der DB steht, kommt meine korrekte Meldung (bereits in Verwendung).

Das mit dem unique in der email Spalte habe ich wieder rückgängig gemacht, war totaler Quatsch. Es wird nun beim Absenden des Formulares zuerst geprüft, ob die Email Adresse in der DB bereits vorhanden ist, und wenn ja, wird auch kein neuer Eintrag mit der gleichen Mailadresse erzeugt. Nur mein Problem: Wenn statt [email protected] > [email protected] eingegeben wird, wird der bereits bestehende Eintrag [email protected] nicht mehr erkannt und ein neuer als [email protected] erzeugt.

Das ist blöd, denn so könnte ein User das ja umgehen indem er einfach irgendwelche Buchstaben der Mailaddy groß schreibt. ;)

Wie kann ich es so machen, dass nicht zwischen Groß- und Kleinschreibung unterschieden werden soll?

Edit: Habe nun diesen Schnipsel drin um zu prüfen ob ein Eintrag in der email Spalte bereits vorhanden ist:
PHP:
$badwords_erg=mysql_query("SELECT * FROM `maillist`") or die(mysql_error());
                while($badwords=mysql_fetch_assoc($badwords_erg)){
            if(strpos($email,stripslashes($badwords['email']))!==FALSE){
                $ok=FALSE;
                $word=stripslashes($badwords['email']);
            }
	}

Gruß
 
Zuletzt bearbeitet:
Die simpelste Lösung wäre es wohl, ein (mb_)strtolower auf die Mailadresse anzuwenden, bevor du sie in die DB einträgst oder in DB-Anfragen verwendest.

- http://php.net/manual/en/function.mb-strtolower.php

Edit: ↓ Ja, klingt sinnvoll. Wobei du dann natürlich wieder entscheiden musst, was passiert, wenn dieselbe Adresse in einem anderen Format eingetragen wird. Update?
 
Zuletzt bearbeitet:
Ich würde beide Formate speichern, so wie vom Benutzer eingegeben als Information und mit strtolower oder strtoupper als Unique Key. Wenn du dem Problem mit Adressänderungen umgehen willst, dann musst den Benutzern halt doch die Möglichkeit eines Anmeldenamen einräumen und bei dem überlegen, ob er Case Sensitive sein soll (würde ich nicht machen).
 
Zuletzt bearbeitet:
Danke,

@mermshaus
Du meinst, wenn jemand [email protected] einträgt? Habe es nun so gemacht, dass auch beim Eintrag in die DB direkt die Eingabe der Mailadresse in Kleinbuchstaben umgewandelt wird, funktioniert.
Somit kann der Benutzer zwar eingeben was er will, [email protected] oder wie auch immer, der Wert wird aber nur einmalig in der DB gespeichert, in Kleinbuchstaben. Wenn er es nun mit anderen Großbuchstaben versucht, kommt immer meine Meldung "Mailadresse bereits in Verwendung". Brauche also an dem geposteten Snippet gar nichts zu ändern, lediglich das hier:

PHP:
$email2 = $_POST['email'];
$email = mb_strtolower($email2);

Somit war's das, es sei denn ich habe wieder irgendwas übersehen :-D
 
Where LOWER() wird in der DB ausgeführt und dann wird u.U. kein Index mehr verwendet. Bei großen Tabellen (wo bei groß bei Oracle oder DB2 sicher anders als bei SQLite oder Access ist) würde ich daher bei häufig verwendeten Keys immer das Abspeichern als strtolower vorziehen, um einen möglichen Full Table Scan zu vermeiden.
 
Wobei duplicate Key ja nur besagt, dass du die Mailadresse indizierst, ist das denn notwendig?
Ich würde keinen Index (primary key) über Mailadressen anlegen, wozu auch.
 
Na ja, für schnellere Lookup-Abfragen von E-Mail-Adressen. Wenn es dumm läuft, muss MySQL ohne Index bei einer Abfrage mit etwa WHERE `email` = '[email protected]' die gesamte Tabelle durchrattern, weil diese Zeile blöderweise die letzte ist, die durchlaufen wird. Da dürftest du im Schnitt auf eine linear wachsende Laufzeit kommen (O(n/2)), während es mit Index logarithmisch anwachsend wird.

Einen Primärschlüssel würde ich daraus aber auch nicht machen.
 
Stimmt voll und ganz, wenn ich die Daten aufheben und nachschlagen möchte. In diesem speziellen Fall wird ja nur ein Kontrolleintrag gemacht, der ein doppeltes Versenden verhindern soll. Ein Index ohne Duplikate verhindert aber nach einmaligem Versandt ein erneutes senden für immer (So ja auch das Problem).

Mal davon abgesehen scheint mir da ohnedies ein Design-Fehler vorzuliegen.
Besser wäre es doch, für das Mailformular einen temporären Timestamp in Kombination mit der Mailadresse zu setzen und ein erneutes Senden z.B. für 10-15 Sekunden zu verhindern. Ein Zusammengesetzter Schlüssel also.
 
Besser wäre es doch, für das Mailformular einen temporären Timestamp
So ähnlich habe ich das gelöst. Pro Session darf ein Benutzer maximal x-einstellbare Mails versenden. Dann muss er dafür sorgen, dass es eine neue Session gibt. Für ein Kontaktformular reicht das aus und die Benutzer, die irgendwann in ihrem Leben eine zweite oder dritte Mail schreiben, die verkraftet eine History-Tabelle locker.
 
sysop schrieb:
Stimmt voll und ganz, wenn ich die Daten aufheben und nachschlagen möchte.

Ja, da ist auch was dran. Für den Anwendungsfall in diesem Thread wäre ein Index sicherlich übertrieben. Falsch ist er aber nicht. Ich sage mal: Kann man halten wie ein Dachdecker. ;)

Besser wäre es doch, für das Mailformular einen temporären Timestamp in Kombination mit der Mailadresse zu setzen und ein erneutes Senden z.B. für 10-15 Sekunden zu verhindern.

Hm, ich war davon ausgegangen, dass das sowieso passiert. Geht doch gar nicht anders, da die Adresse ja sonst für alle Zeiten blockiert ist.

NetAktiv schrieb:
Pro Session darf ein Benutzer maximal x-einstellbare Mails versenden. Dann muss er dafür sorgen, dass es eine neue Session gibt.

Oder du sagst: Pro Session darf ein Benutzer nur „x Mails pro y Minuten“ versenden.

Was den Schutz vor Spam angeht, sind die Lösungen aber leider alle leicht auszuhebeln.
 
Was den Schutz vor Spam angeht, sind die Lösungen aber leider alle leicht auszuhebeln.
Zusätzlich habe ich noch so ein Captcha (OK, auch dafür gibt es Hebel) und die Mails gehen alle an mich als CC, so erfahre ich es recht schnell. In meinem Basiscode kann ich noch eine Liste von Deny-IPs pflegen, um Spamer auszuschließen, wenn ich sie mal erwischt habe. Ich musste 1Mal rund 500 Einträge aus meinem Gästebuch löschen, das war aber bisher zum Glück alles. Problematischer war für mich bisher, dass Spamer tausende von Mails in meinem Namen von einem anderen SMTP-Server versendeten und all die ungültig Adressierten landeten bei mir, da ich eine Catch-All Mailbox eingerichtet hatte (die Absender wurden zufällig erzeugt im stil [email protected]). Ich betreibe Aufwand nur dann, wenn entweder etwas passiert ist oder es eine mit geringem Aufwand integrierbare fertige kostenlose Lösung gibt.
 
Ich habe das übrigens mehr als deprimierte allgemeine Feststellung gemeint, nicht irgendwie als Kritik, falls das so ankam.

Ich finde es ganz schrecklich, die User Experience durch Dinge wie Captchas oder andere Anti-Spam-Techniken zu verschlechtern. Schon klar, dass es im Zweifel nicht anders geht.
 
Zurück
Oben