Webdesign Tutorial 2: PHP Gästebuch

Kostenlose Gästebücher gibt es einige im Netz. Doch leider ist die Anpassung ans eigene Design meist recht umständlich oder garnicht umsetzbar. Es scheitert die Integration in die eigene Seite da man nicht extra auf iframes umstellen will, die Optik lässt sich nicht nahtlos übertragen und zum Schluss wird die eigene Homepage noch von Werbung zugemüllt.

Deshalb hier ein kleines Tutorial wie man via PHP und MySQL ein eigenes Gästebuch erstellt. Die Endversion könnt ihr auf meiner Seite betrachten
-> drivers book

Schritt 1 - Datenbankstruktur:

Eine MySQL-Datenbank bildet unser Backend. Dort werden alle Gästebucheinträge gespeichert. Sicher ist auch die Variante mit einer Textfile möglich - doch wenn man scha ne Datenbank zur Verfügung hat... zudem is die Administration später etwas einfacher (find ich jedenfalls).

Also... Tabellen anlegen. Dazu gehen wir in unser phpmyadmin, auf die Datenbank und erstellen eine Tabelle namens "book" oder "buch" oder wie ihr sie auch nennen wollt (um sauber zu bleiben, einen Namen ohne Umlaute - also kein "gästebuch"). Dazu einfach in das Feld auf der Startseite unter "Neue Tabelle in Datenbank name erstellen" den Namen der Tabelle eintragen. In das hintere Feld wird die Anzahl der benötigten Felder eingetragen. Je nachdem wieviel man speichern will, ich nehm mal 6.

book tutorial

Nach Anlegen der Tabelle können die einzelnen Felder mit Namen und Typ belegt werden.

book tutorial

FeldBedeutung
IDeindeutige ID - wird automatisch erstellt
vonName des Erstellers
amZeitstempel
maileMail des Erstellers
hpHomepage des Erstellers
textder eigentliche Eintrag


Wer will kann noch Dinge wie Herkunft, Bewertung der Seite etc abfragen. Dazu einfach noch die entsprechenden Felder hinzufügen.

Schritt 2 - Eingabemaske

<form action="/book_action" method="post">
<table summary="eintrag hinterlassen">
<tr>
<td>Name:</td>
<td><input type="text" name="name" size="70" /></td>
</tr>
<tr>
<td>Email:</td>
<td><input type="text" name="mail" size="70" /></td>
</tr>
<tr>
<td>Homepage:</td>
<td><input type="text" name="hp" size="70" value="http://" /></td>
</tr>
<tr>
<td>Text:</td>
<td><br/></td>
</tr>
<tr>
<td colspan="2"><textarea name="text" cols="63" rows="5"></textarea></td>
</tr>
<tr><td><br/></td></tr>
<tr>
<td style="text-align:center;" colspan="2"><img src="captcha/captcha.php" border="0" title="Sicherheitscode" width="140" height="40" alt="Sicherheitscode" /><br/>
<input type="text" name="sicherheitscode" size="20" /></td>
</tr>
<tr><td><br/></td></tr>
<tr>
<td><input type="submit" value="eintragen" /></td>
<td style="text-align:right;"><input type="reset" name="formsend" value="abbrechen" /></td>
</tr>
</table>
</form>



Nachdem die Datenbank steht, müssen die Einträge natürlich irgendwie reinkommen. Dazu erstellen wir uns eine einfache PHP Seite mit einem Formular und den diversen Forumlarfeldern, die wir oben in unserer Datenbank definiert haben.

Übersichtshalber hab ich die Maske und den eigentlichen Speichervorgang in zwei unterschiedliche Dateien gespeichert - man kann natürlich auch beides in eine schreiben.

Die "Speicherseite" wird im Formular als "action" angegeben, die restlichen Inputfelder dürfte jeder kennen, falls nicht bitte hier nachlesen.

Attribute:
Man könnte zusätzlich bei allen Feldern einen value-Wert hinterlegen (z.B. "bitte einen Namen eintragen") und dann evtl. beim Klicken auf das Feld (onfocus) den Text löschen lassen.

Damit die Sicherheit nicht zu kurz kommt und Spambots nicht unser schönes Gästebuch zunichte machen (hatt ich am Anfang, sehr ärgerlich) hab ich unten ein bekanntes Captcha hinzugefügt. Eine ziemlich gute Erklärung dazu findet ihr hier: Anleitung Captcha

Schritt 3 - Speichern

a) Prüfungen

session_start(); if ('POST' == $_SERVER['REQUEST_METHOD']) {
if (!isset($_POST['name'], $_POST['mail'], $_POST['text'],$_POST['hp'], $_POST['formsend'])) {
die ('Benutzen sie nur Formulare von der Homepage.');
}
} else {
if(isset($_SESSION['captcha_spam']) AND $_POST["sicherheitscode"] == $_SESSION['captcha_spam'])
{
unset($_SESSION['captcha_spam']);

$name = $_POST['name'];
$mail = $_POST['mail'];
$hp = $_POST['hp'];
$text = $_POST['text'];

###################################

//Welche Felder ausgefüllt werden müssen
if ($name == ""
|| $mail == ""
|| $text == ""
) {

$error = "yes";
echo "<Script>alert('Bitte überprüfen Sie, ob alle Pflichtfelder ausgefüllt sind!)</script>";
echo "<Script>history.back(-1)</script>";
exit();
}

if ($hp == "http://")
{
$hp = "";
}

// E-Mail-Adresse wird geprüft
if (!ereg("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,3})$", $mail))
{
$error = "yes";
echo "<Script>alert('Bitte prüfen Sie, ob Ihre E-Mail-Adresse korrekt ist!')</script>";
echo "<Script>history.back(-1)</script>";
exit();
} } }



Ganz oben ist wieder die Sicherheitsabfrage unseres Captchas zu finden (siehe Link).
Darunter werden die 4 von der Eingabemaske übergebenen Werte abgefangen. Achtet darauf, dass der Name (des was hinter POST in den Hochkommas steht) mit dem Name-Attribut eurer Eingabemaske übereinstimmt, da sonst die Felder nicht erkannt werden.

Anschließend werden die Pflichtfelder auf Inhalt überprüft. Dazu zählen logischerweise der Name sowie der Text, ich hab mir noch erlaubt auch die eMail als Pflichtfeld zu hinterlegen.

Die nächste Prüfung behebt im Prinzip "nur" einen Schönheitsfehler. Da wir mit dem value-Wert in der Eingabemaske für die Homepage bereits das "http://" vorgegeben haben und nicht jeder Besucher die angefangen URL wieder löscht, bereinigen wir diese. Lassen wir diese Prüfung weg, müsste später beim Auslesen der Datenbank abgefangen werden ob eine "echte" URL hinterlegt ist. Ansonsten würde dem User ohne Homepage eine leere "http://"-Webseite zugewiesen.

Die letzte Prüfung befasst sich mit der Korrektheit der eMailadresse. Also dass diese im Format name@anbieter.xx hinterlegt ist.

Bei den 2 Prüfungen, die Aufgrund eines Eingabefehlers fehlschlagen, werden jeweils JavaScript-Alerts ausgegeben und auf die Eingabemaske zurückgeworfen (history.back). Eine andere Ausgabe, z.b. aufrufen einer weiteren "Error-Seite" ist ebenfalls möglich.

b) In die Datenbank schreiben

if ($error != "yes")
{
db_connect();
$sql="insert into book(von,mail,hp,text,am) values('".mysql_real_escape_string(htmlentities($name)).
"','".htmlentities(mysql_real_escape_string($mail)).
"','".htmlentities(mysql_real_escape_string($hp)).
"','".htmlentities(mysql_real_escape_string($text))."',NOW())";
$result = mysql_query($sql);
db_disconnect();

//Fehler
if ($result!="")
{
echo "<Script>window.location='/book'</script>";
exit();
}
else
{
echo "<Script>alert('Ein Fehler ist aufgetreten!')</script>";
echo "<Script>history.back(-1)</script>";
exit();
}



Die Funktionen db_connect() und db_disconnect() öffnen bzw. schließen die Datenbankverbindung. Sind bei mir in einer weiteren PHP-File hinterlegt, da ich diese Funktionen logischerweise öfter benötige. Die entsprechende PHP-File wird am Anfang via include in die book_action.php includiert.

include('config.php');



Das eigentliche Hinzufügen ist ein einfacher insert Befehl. Für die, die des SQL nicht mächtig sind:

Achtet darauf, dass die Reihenfolge der Felder mit der der Übergabewerte übereinstimmt. Nicht dass die eMail dann beim Namen steht.

c) Restliche Prüfungen

//Wenn nicht alles ausgefüllt wurde
} else
{
echo "<Script>alert('Ein Fehler ist aufgetreten! Bitte prüfen Sie Ihre eingaben!')</script>";
echo "<Script>history.back(-1)</script>";
exit();
}
//Falsches Captcha
} else
{
echo "<Script>alert('Ein Fehler ist aufgetreten! Bitte prüfen Sie Ihre eingaben!')</script>";
echo "<Script>history.back(-1)</script>";
exit();
}



Anschließend wird noch geprüft ob der Schreibvorgang erfolgreich war und die Daten in die DB eingetragen wurden. Die letzten zwei Prüfungen beziehen sich auf die Eingaben ($error!="yes") und die Captcha-Abfrage am Anfang.

d) Test

Somit sollte die Eingabefunktion vollständig sein. Ihr könnt jetzt testweise mal einen Beitrag über die Maske in die Datenbank schreiben. Falls der Versuch scheitert evtl. mal Ausgaben (print) an diverse markante Stellen setzen. Wie z.b. vor der Captcha-abfrage welcher Sicherheitscode übergeben wurde, vor der ersten Prüfung, ob alle Werte übergeben wurden, und evtl. in die Prüfungen ob die Verarbeitung richtig ist. So könnt ihr euch auch nach und nach rantasten wo das eigentliche Problem liegen könnte. Also ob die Übergabe scheitert, die Verbindung zur Datenbank fehlschlägt oder eine Prüfung mist baut.

Schritt 4 - Gästebuch (Datenbank auslesen)

Um die Sache etwas bildlicher zu erklären gehen wir davon aus, dass in unserem Gästebuch 23 Einträge stehen die nun angezeigt werden sollen. Dabei sollen die 23 Einträge auf 3 Seiten verteilt werden (10 pro Seite), wobei der neueste Beitrag auf Seite 1 oben steht.

a) Definitionen

$i=1;
$zahl=0;
$show=10;

db_connect();
$result_a = mysql_query("select count(id) as anz, max(id) as maxi from book");
$anz = mysql_fetch_assoc($result_a);
$max = $anz['anz'];
$mid = $anz['maxi'];
$seiten = ($max / $show) +1;
mysql_free_result($result_a);




Anmerkung: ich geb zu, manche Bezeichnung sind nicht optimal, sind eben "mit der Zeit gewachsen" ;)

b) Seitenzahlen

echo "<table class='book' summary='gaestebuch'><tr><td>" . $max . " Einträge auf " . (int)$seiten . " Seiten</td><td>Seite ";
while ($i <= $seiten)
{
echo "<a href='index.php?side=book&id=" . $mid . "&t=" . $zahl . "'>". $i . "</a> | ";

$result_b = mysql_query("select id from book where id <=" . $mid . " order by id desc LIMIT " . $show);
while ($sid = mysql_fetch_array($result_b)) { $sarray[$i] = $sid['id']; }
$mid = min($sarray)-1;
mysql_free_result($result_b);

$zahl = $zahl + $show;
$i++;
}
echo "</td></tr></table><table class='book' summary='einträge'>";
$i=0;



Nach Ausgabe der Information über die Anzahl der Einträge und deren Verteilung (n Seiten), läuft die Schleife solange durch, bis der Zähler $i die Anzahl der Seiten erreicht hat. Bei uns wärens dann eben 3.

Die ausgegebenen Links verweisen dann auf die selbige Seite, übergeben wird pro link die Größte id der Seite sowie die bereits abgearbeiteten Einträge.
Beim "erst-laden" der Seite wird die id auf 999 gesetzt, die abgearbeiteten Sätze logischerweise auf 0. Also bei 1000 Beiträgen müsste man den Wert noch mal erhöhen. *g

Beispiel:

Anmerkung: die id muss bei 23 Sätzen logischerweise nicht immer 23 sein. Mal paar Spams gelöscht, schon hat man Größere ids als Sätze in der Datenbank. Stellt aber kein Problem dar. Denn durch die Schleife wird jedesmal die aktuell kleinste id der 10er Gruppe ermittelt.

c) Einträge auslesen

$result = mysql_query("select id,von,mail,hp,text, DATE_FORMAT(am,'%d.%m.%Y') as datum from book where id <=" . $id . " order by id desc LIMIT " . $show);
while($liste = mysql_fetch_array($result))
{
$text = str_replace(
array('ä', 'ö', 'ü', 'ß'),
array('&auml;', '&ouml;', '&uuml;', '&szlig;'),
$liste['text']
);
$text = nl2br($text);

$wert = $max - $i - $it;
echo "<tr class=\"gbhead\">";
echo "<th style='width:400px;'><a href='mailto:" . $liste['mail'] . "'>" . $liste['von'] . "</a> schrieb am " . $liste['datum'] ."</th>";
echo "<td>Eintrag Nr: " . $wert . "</td></tr><tr>";
echo "<td colspan='2'>" . $text . "</td></tr><tr><td></td></tr>";
if ($liste['hp'] != "")
{
echo "<tr><td colspan='2'>Homepage: <a href='" . $liste['hp'] . "' target='_blank'>" . $liste['hp'] . "</a></td></tr>";
}
echo "<tr><td><br/><br/></td></tr>";
$i++;
}
mysql_free_result($result);
db_disconnect();



Mit bekannter SQL-Anweisung von oben besorgen wir uns wieder die ersten 10 Datensätze dieser Seite. Also bei Seite 2 z.b. die 10, die ne kleinere id haben als 13.

Nachdem in der Schleife die Umlaute maskiert und die Zeilenumbrüche ersetzt wurden, ermitteln wir den Wert des aktuellen Gästebucheintrags. Dazu nehmen wir die Anzahl aller Datensätze ($max), ziehen davon zuerst die bereits auf der Seite geschriebenen ab ($i), anschließend noch die bereits auf der Vorderseite Verarbeiteten.

Beispiel:

Der Rest ist vermutlich selbsterklärend. Eine Tabelle in der die Werte hineingelesen werden. Dabei wird die Kopfzeile noch mit einer class versehen um sie farblich vom Rest abzuheben (ich hab dafür schwarzen Hintergrund, weiße Schrift genommen).

.gbhead { background-color:#000000;color:#ffffff; }



Zum Schluss kommt noch die Homepageprüfung. Wenn kein Wert hinterlegt ist, wird kein Link angezeigt.

d) Eintrag erstellen

<a href="/book_add" class="entry">Eintragen</a>



Damit schließt sich der Kreis. Über den Link (ihr könnt auch eine Grafik o.ä. benutzen) gelangt man wieder zur Eingabemaske.

Fertig

So, nun solltet ihr ein schickes Gästebuch euer Eigen nennen können. Falls Fragen dazu auftreten könnt ihr mich unter meiner ICQ-Nummer erreichen.

Vielleicht noch als Information: ich hab des Gästebuch erstellt im Zuge meiner "PHP-Lernphase", durchaus möglich, dass manche Dinge einfacher zu lösen wären.
aber was solls....es läuft ja :)