Systemvoraussetzung
- Linux
- Windows
- PHP 3
- PHP 4
- PHP 5
- MySQL
Datei(en)
formSend.php, formSend.sql
Problem
Wer kennt das leidige Thema nicht: Ein Besucher hat ein Formular ausgefüllt
und drückt dann versehentlich zweimal hintereinander auf den Senden-Button.
Oft passiert es auch, dass der Besucher nach dem Senden die Seite aktualisiert
oder eine Seite zurückgeht und somit das Formular eventuell neu versendet.
In der Datenbank finden sich dann mehrere gleiche Einträge, die da nicht
hingehören und ausgefiltert werden müssen. Das ist nicht nur zeitaufwändig,
sondern auch ärgerlich. Wir müssen also eine Lösung finden, die dieses
unterbindet.
Lösung
Die Lösung hierfür ist relativ simpel und schnell programmiert. Alles, was wir
benötigen, sind ein zusätzliches Feld in unserer Datenbank und eine eindeutige
Kennung. Anhand dieser Kennung können wir dann in der Datenbank nachschauen,
ob dieses Formular bereits gesendet wurde oder nicht. Vor jedem
neuen Aufruf des Formulars wird eine derartige Kennung erzeugt und jeweils
mit dem Datensatz des Formulars in die Datenbank gespeichert.
Wir überprüfen (3) bei jedem Aufruf der Seite, ob die übermittelte Variable
„checkID“ leer oder nicht existent ist. Sollte das der Fall sein, erstellen wir anhand
der aktuellen Zeit in Sekunden und Mikrosekunden eine MD5-Prüfsumme
(5) und speichern diese in die POST-Variable.
Wurde eine Prüfsumme übermittelt, also das Formular abgesendet, so überprüfen
wir im ersten Schritt, ob es sich um eine gültige Prüfsumme handelt (10).
Unsere Prüfsumme muss aus 32 Zeichen bestehen und darf nur Zahlen und
Buchstaben enthalten.
Handelt es sich um keine gültige Prüfsumme, brechen
wir den Vorgang ab (37) und geben eine Fehlermeldung aus (39).
Handelt es sich bei der Variablen um eine gültige Prüfsumme, können wir den
weiteren Test einleiten. Dafür stellen wir mit unseren DatenbankZugangsdaten
(12-15)
eine Verbindung zum MySQLServer
her (17-18).
Der nächste Schritt ist die eigentliche Überprüfung der Prüfsumme (20). Wir
fragen innerhalb der Datenbank nach, ob bereits eine identische Prüfsumme
vorliegt. Falls ja, so liefert uns die MySQL-Anfrage
genau einen Treffer (22), da
die Spalte für die Prüfsummen in der Datenbank auf UNIQUE gesetzt ist und
somit nur eindeutige Prüfsummen enthalten sein können.
Lieferte die Anfrage keinen Eintrag zurück (26), können wir sicher sein, dass
das Formular nur einmal gesendet wurde. Wir speichern (28) die Daten aus
dem Formular und überprüfen (30), ob sie korrekt gespeichert wurden.
Je nachdem, ob es zu einem Fehler kam oder nicht, wird ein entsprechender
Hinweistext ausgegeben. Sollte der Besucher versehentlich das Formular zweimal
gesendet haben, wird dieser Datensatz nicht gespeichert. Die eindeutigen
Prüfsummen in der Datenbank verhindern dies.
Sie können davon ausgehen, dass die Prüfsummen einmalig sind, da sie aus
der aktuellen Zeit in Sekunden und Mikrosekunden erstellt wurden. Diese
gleiche Zeit wird es in der Zukunft nicht mehr geben und daher auch nicht die
Prüfsumme. Die Wahrscheinlichkeit, dass zwei Personen zur gleichen Zeit (Sekunde
und Microsekunde) das Formular aufrufen, ist ebenfalls verschwindend
gering und kann vernachlässigt werden.
01: 02: 03: 04: 05: 06: 07: 08: 09: 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: |
<?PHP
if(empty($_POST['checkID'])) { $_POST['checkID'] = md5(microtime()); } else {
if(preg_match('/^[a-f0-9]{32}$/',$_POST['checkID']))
{ $db_host = "localhost"; // MySQL Hostname $db_name = "db1042434-test"; // MySQL Datenbankname $db_user = "dbu1042434"; // MySQL Benutzername $db_pass = "up24TzF"; // MySQL Passwort
$dbCon = @MYSQL_CONNECT($db_host,$db_user,$db_pass)
or die("Datenbank momentan nicht erreichbar"); $db_check = @MYSQL_SELECT_DB($db_name)
or die("Datenbank momentan nicht erreichbar"); $sqlCheck = @mysql_query("SELECT id FROM formSend WHERE
checkID = '".$_POST['checkID']."'"); if(@mysql_num_rows($sqlCheck) == 1) { $message = 'Ihre Daten wurden bereits gespeichert!'; } else { $sqlInsert = @mysql_query("INSERT INTO formSend (vorname,
name, checkID) VALUES ('".$_POST['vorname']."','".
$_POST['name']."','".$_POST['checkID']."')"); if(@mysql_affected_rows() == 1) $message = 'Ihre Daten wurden gespeichert!'; else $message = 'Ihre Daten konnten nicht gespeichert werden!'; }
} else { $message = 'Checksumme wurde manipuliert oder ist fehlerhaft!'; } } ?> |
Beispiel 3.4: formSend.php
Der nachfolgende HTML-Quellcode
sollte selbsterklärend sein. Allerdings sollten
Sie sich die Speicherung (65) des hiddenFields
und die Fehlermeldung (51)
anschauen. Die Fehlermeldung müssen Sie nicht in Ihr Formular einbauen, das
ist Ihnen überlassen. Sie müssen allerdings unbedingt das hiddenField
mit der
Check-Summe
in Ihrem Formular verwenden, da sonst der Schutz nicht greift.
HTML-Quellcode
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: 74: 75:
| <html>
<head> <title>Mehrfaches Absenden eines Formulars verhindern</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link href="formStyle.css" rel="stylesheet" type="text/css"> </head>
<body> <span class="table"><?PHP echo $message; ?></span> <form name="form1" method="post" action="formSend.php"> <table width="100%" border="0" cellspacing="0" class="table"> <tr> <td width="7%">Vorname</td> <td width="93%"> <input name="vorname" type="text" class="inputField"
value="<?PHP echo $_POST['vorname']; ?>"> </td> </tr> <tr> <td>Name</td> <td><input name="name" type="text" class="inputField"
value="<?PHP echo $_POST['name']; ?>"></td> </tr> <tr> <td><input name="checkID" type="hidden"
value="<?PHP echo $_POST['checkID']; ?>"></td> <td> </td> </tr> <tr> <td> </td> <td><input name="Submit" type="submit" class="button"
value="Abschicken"></td> </tr> </table> </form> </body> </html>
|
Beispiel 3.5: formSend.php
Nachfolgend sehen Sie die Ausgabe im Browser. Selbstverständlich können
uns sollten Sie die Fehlermeldung an Ihre Bedürfnisse anpassen, zumal in
diesem Beispielskript keine Überprüfung der Variablen für Vorname und Name
durchgeführt wurde.
Im vorherigen Kapitel wurde bereits gezeigt, wie Sie Ihre Fehlermeldung generieren
können. Eine Kombination mit diesem Programm wäre wünschenswert
und anzuraten. Sie werden es selbst sicher zu schätzen wissen, denn nicht nur
die Fehlermeldungen sind aussagekräftig, sondern auch die Dubletten in der
Datenbank gehören danach der Vergangenheit an.
Abbildung 3.3: Ausgabe im Browser
Dieses Skript aus dem SELFPHP KOCHBUCH wurde von SELFPHP unter dem "Tarif Mc500" von McAc.net-Webhosting erfolgreich ausgeführt und getestet!
Auf der Übersichtseite unter "McAc.net – Webhosting zu diesem Buch" finden Sie weitere Informationen zu dem Webhostingpaket, dass durch SELFPHP getestet wurde.
|