Unsere eigene Shoutbox mit PHP und der ADODB


Vorbereitung
BEVOR IHR LOSLEGT:
Lest bitte vorher die Informationen zur ADODB hier http://www.traum-projekt.com/forum/7...dodb-fuer.html .

Ich gehe hier davon aus, dass sich die ADODB-Libraries im Ordner "adodb5" im gleichen Ordner wie die restlichen PHP-Dateien befinden.
Das ist natürlich Geschmackssache, ihr müsst dafür auch bloß den Pfad bei "require_once" anpassen.


Die Datenbank
Wir benötigen keine komplett dedizierte Datenbank, eine einzelne Tabelle reicht.
Hier ist die CREATE-Anweisung für die Datenbank:

Code:
CREATE TABLE `shoutbox` (
`ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`CreateDateTime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`Visible` BOOL NOT NULL ,
`AuthorName` VARCHAR( 240 ) NOT NULL ,
`AuthorEmail` VARCHAR( 240 ) NOT NULL ,
`AuthorIPAddress` VARCHAR( 128 ) NOT NULL ,
`Message` TEXT NOT NULL
) ENGINE = MYISAM ;

Das Encoding habe ich absichtlich nicht angegeben, weil es ja auch vom Zeichensatz des restlichen Projekts abhängt - aber im Auslieferungszustand hat die ADODB bei mir immer etwas Probleme mit UTF-8 bereitet. Es mag sein, dass das inzwischen beseitigt wurde, ich wollte auch nur erstmal warnen.
Für sachdienliche Hinweise, die zur Kompatibilität mit UTF-8-Datenbanken führen, wäre ich sehr dankbar


Das Formular

Hier ist unsere shoutbox.php, die erstmal nur unser Formular enthält:
(JA, ich weiß - valide mag anders sein, aber ich bin Web-Entwickler und nicht Web-Designer )

PHP-Code:

<html>
<
head>
<!-- 
Hier der ganze HTML-Schmonses... -->
</
head>
<
body>

<
h3>Meine großartige Shoutbox</h3>

<
form name="shoutbox" action="shoutbox.php" method="POST">

<
p>
    
Dein Name:<br>
    <
input type="text" name="Shoutbox[AuthorName]">
</
p>

<
p>
    
Deine E-Mail-Adresse:<br>
    <
input type="text" name="Shoutbox[AuthorEmail]">
</
p>

<
p>
    
Deine Nachricht:<br>
    <
textarea name="Shoutbox[Message]"></textarea>
</
p>

<
p>
    <
input type="submit" value="Eintragen">
</
p>

</
form>

</
body>
</
html

Ein paar Erklärungen dazu:
Wie dem aufmerksamen Leser nicht entgangen sein mag, stimmen die Indexe der Formularfelder mit denen in der Datenbank überein. Warum das so ist, wird im nächsten Schritt klar, es nimmt uns nämlich besonders bei großen Formularen eine Menge Arbeit ab.



Der Aufbau der Datenbankverbindung
Wir nehmen unsere eben erstellte shoutbox.php und fügen über dem bestehenden Inhalt den Code für den Verbindungsaufbau zur Datenbank ein.

PHP-Code:

<?php

// ##########################################
// ### Verbindung aufbauen                ###
// ##########################################

// ### Einbinden der ADODB-Klassen
require_once("./adodb5/adodb.inc.php");

// ### Objektinstanz erzeugen und Verbindung konfigurieren
$oDB = new ADONewConnection("mysql");

// ### Verbindung herstellen
// ### Angabe von Server, Benutzername, Kennwort und Datenbankname
$oDB->Connect("localhost""root""passwort""datenbank");

// ### Wenn Verbindung fehlschlägt, brechen wir hier ab
if(!$oDB->IsConnected())
    die(
"Datenbankverbindung fehlgeschlagen!");
Damit steht schonmal unsere Datenbankverbindung. Jetzt speichern wir die Daten aus der Shoutbox in der Datenbank


Speichern in der Datenbank
Damit wir was von der Shoutbox haben, müssen wir die Daten in der Datenbank speichern.
Den folgenden Code fügen wir zwischen dem Verbindungsaufbau und dem Formular ein:

PHP-Code:

// ### Prüfen, ob die benötigten Teile des Formulares ausgefüllt sind
if(strlen($_POST['Shoutbox']['AuthorName']) > && strlen($_POST['Shoutbox']['Message']) > 0)
{
    
// ### Ja, sind sie :-)
    
    // ### Wir bereiten die Daten etwas vor:
    // ### Erst kopieren wir die POST-Daten aus dem Formular in ein eigenes Array
    
$InsertArray $_POST['Shoutbox'];
    
    
// ### Dann setzen wir bestimmte Felder bzw. überschreiben die Werte, damit uns die keiner von außen manipuliert
    
$InsertArray['Visible'] = 1;
    
$InsertArray['CreateDateTime'] = time();
    
$InsertArray['AuthorIPAddress'] = $_SERVER['REMOTE_ADDR'];
    
$InsertArray['ID'] = null;

    
// ### Insert in die Datenbank    
    
if(!$oDB->$oDB->AutoInsert("shoutbox"$InsertArray"INSERT"))
        die(
"Aua.. Da ist ein Fehler aufgetreten!");
}

?> 
Jetzt zeigt sich, warum die Formularfelder den gleichen Namen haben wie die Datenbankfelder.
Wir brauchen die Variablen (besonders bei großen Formularen) nicht mehr einzeln irgendwie zuweisen,
sondern geben der ADODB einfach das gesamte $_POST-Array. In der Datenbank nichtexistente Felder werden dabei
einfach ignoriert.


Ausgabe der Daten
Nachdem wir nun die Daten speichern können, müssen wir sie irgendwie wieder ausgeben
Der nachfolgende Codeschnipsel ruft die letzten 20 Einträge ab und gibt sie aus.

Diesen Codeschnipsel fügen wir an der shoutbox.php nach dem </form>-Tag ein:

PHP-Code:

<?php

// ### Die letzten 20 freigeschalteten Einträge abrufen
$TabEntries $oDB->Execute('SELECT * FROM `shoutbox` WHERE `Visible` = 1 ORDER BY `ID` DESC LIMIT 20');

// ### Abfrage erfolgreich, sonst ist $TabEntries === false
if($TabEntries != false)
{
    
// ### Alle Einträge durchlaufen
    
while($TabEntries->EOF !== true)
    {
        
// ### Wir erzeugen ein temporäres Array, in das wir alles, was wir ausgeben wollen, zwischenspeichern.
        // ### Hat außer mehr Übersichtlichkeit keine nennenswerten Vorteile...
        // ### Mit htmlentities() werden HTML-Tags unschädlich gemacht, so dass uns niemand JavaScript oder sonstwas unterschieben kann
        
$EchoArray = array();
        
$EchoArray[] = '<p>Eintrag Nr. '.$TabEntries->Fields("ID").'<br>';
        
$EchoArray[] = 'von <strong>'.htmlentities($TabEntries->Fields("AuthorName")).'</strong>, ';
        
$EchoArray[] = 'eingetragen um '.date('d.m.Y / H:i'strtotime($TabEntries->Fields("CreateDateTime")) ).'<br>';
        
$EchoArray[] = 'Nachricht:<br>';
        
$EchoArray[] = nl2br(htmlentities($TabEntries->Fields("Message")));
        
$EchoArray[] = '</p><br>';
        
        
// ### Zusammengefügtes Array ausgeben
        
echo implode("\n"$EchoArray);
    
        
// ### Nächsten Eintrag holen
        
$TabEntries->MoveNext();
    }
}

?>


Zum Abschluss noch die gesamte shoutbox.php:

PHP-Code:

<?php

// ##########################################
// ### Verbindung aufbauen                ###
// ##########################################

// ### Einbinden der ADODB-Klassen
require_once("./adodb5/adodb.inc.php");

// ### Objektinstanz erzeugen und Verbindung konfigurieren
$oDB = new ADONewConnection("mysql");

// ### Verbindung herstellen
// ### Angabe von Server, Benutzername, Kennwort und Datenbankname
$oDB->Connect("localhost""root""passwort""datenbank");

// ### Wenn Verbindung fehlschlägt, brechen wir hier ab
if(!$oDB->IsConnected())
    die(
"Datenbankverbindung fehlgeschlagen!");


// ### Prüfen, ob die benötigten Teile des Formulares ausgefüllt sind
if(strlen($_POST['Shoutbox']['AuthorName']) > && strlen($_POST['Shoutbox']['Message']) > 0)
{
    
// ### Ja, sind sie :-)
    
    // ### Wir bereiten die Daten etwas vor:
    // ### Erst kopieren wir die POST-Daten aus dem Formular in ein eigenes Array
    
$InsertArray $_POST['Shoutbox'];
    
    
// ### Dann setzen wir bestimmte Felder bzw. überschreiben die Werte, damit uns die keiner von außen manipuliert
    
$InsertArray['Visible'] = 1;
    
$InsertArray['CreateDateTime'] = time();
    
$InsertArray['AuthorIPAddress'] = $_SERVER['REMOTE_ADDR'];
    
$InsertArray['ID'] = null;

    
// ### Insert in die Datenbank    
    
if(!$oDB->$oDB->AutoInsert("shoutbox"$InsertArray"INSERT"))
        die(
"Aua.. Da ist ein Fehler aufgetreten!");
}

?>

<html>
<head>
<!-- Hier der ganze HTML-Schmonses... -->
</head>
<body>

<h3>Meine großartige Shoutbox</h3>

<form name="shoutbox" action="shoutbox.php" method="POST">

<p>
    Dein Name:<br>
    <input type="text" name="Shoutbox[AuthorName]">
</p>

<p>
    Deine E-Mail-Adresse:<br>
    <input type="text" name="Shoutbox[AuthorEmail]">
</p>

<p>
    Deine Nachricht:<br>
    <textarea name="Shoutbox[Message]"></textarea>
</p>

<p>
    <input type="submit" value="Eintragen">
</p>

</form>


<?php

// ### Die letzten 20 freigeschalteten Einträge abrufen
$TabEntries $oDB->Execute('SELECT * FROM `shoutbox` WHERE `Visible` = 1 ORDER BY `ID` DESC LIMIT 20');

// ### Abfrage erfolgreich, sonst ist $TabEntries === false
if($TabEntries != false)
{
    
// ### Alle Einträge durchlaufen
    
while($TabEntries->EOF !== true)
    {
        
// ### Wir erzeugen ein temporäres Array, in das wir alles, was wir ausgeben wollen, zwischenspeichern.
        // ### Hat außer mehr Übersichtlichkeit keine nennenswerten Vorteile...
        // ### Mit htmlentities() werden HTML-Tags unschädlich gemacht, so dass uns niemand JavaScript oder sonstwas unterschieben kann
        
$EchoArray = array();
        
$EchoArray[] = '<p>Eintrag Nr. '.$TabEntries->Fields("ID").'<br>';
        
$EchoArray[] = 'von <strong>'.htmlentities($TabEntries->Fields("AuthorName")).'</strong>, ';
        
$EchoArray[] = 'eingetragen um '.date('d.m.Y / H:i'strtotime($TabEntries->Fields("CreateDateTime")) ).'<br>';
        
$EchoArray[] = 'Nachricht:<br>';
        
$EchoArray[] = nl2br(htmlentities($TabEntries->Fields("Message")));
        
$EchoArray[] = '</p><br>';
        
        
// ### Zusammengefügtes Array ausgeben
        
echo implode("\n"$EchoArray);
    
        
// ### Nächsten Eintrag holen
        
$TabEntries->MoveNext();
    }
}

?>


</body>
</html>

Ein paar Worte zur Sicherheit
Das Script ist so wie es jetzt ist, erstmal ganz gut gegen SQL-Injections abgesichert.
Es bietet aber keinen Schutz vor Spambots oder (versehentlichem) mehrfachen Eintragen der gleichen Daten durch mehrfaches Absenden des Formulars.
Das hätte den Rahmen dieses Tutorials auch gesprengt, wenn es da noch Interesse gibt, kann ich das nachliefern.


Fehler bitte an mich per PN, Mail oder in diesem Thread!