Kommentarsystem mit Antwortfunktion

Vor einiger Zeit arbeitete ich an einem Projekt und brauchte bzw. wollte das erste Mal ein Kommentarsystem mit Antwortfunktion einbauen. Leider gab es im ganzen World Wide Web nicht wirklich etwas. Folglich habe ich mir das Ganze überlegt und selbst eines gebaut. Als Lösungsansatz diente mir ein rekursiver Funktionsaufruf. Hinweis: Ist wird davon ausgegangen, dass sie bereits ein Newssystem haben. Andernfalls würde ich Ihnen Kapitel 33 aus dem Quakenet PHP-Tutorial ans Herz legen.

Tabellenaufbau

Spalte Beschreibung
id Der eindeutige Schlüssel zur Identifikation eines Kommentars (UNIQUE, PRIMARY, A_I, UNSIGNED)
newsID Zu welcher News gehört das Kommentar? (UNSIGNED)
author Benutzername oder dergleichen (mit VARCHAR 32 dürfte man auskommen)
parentID Übergeordnetes Kommentar (wenn das Kommentar keine Überordnung hat -> 0) (UNSIGNED)
content Das Kommentar selber (TEXT)
date Abschließend noch das Datum (DATETIME)

Daraus ergibt sich folgendes SQL-Statement zum erstellen der benötigten Tabelle:

CREATE TABLE `news_comments` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `newsID` int(10) unsigned NOT NULL,
  `author` varchar(32) DEFAULT NULL,
  `parentID` int(10) unsigned NOT NULL,
  `content` text NOT NULL,
  `date` datetime NOT NULL,
  PRIMARY KEY (`id`)
)

Anzeigen der Kommentare

Zu Beginn benötigt man einmal den Funktionskopf des rekursiven Aufrufs. Übergeben muss man die newsID, die parentID (Standard 0) und einen Zähler (im Sinne von, dass wievielte Unterkommentar bin ich? | Standard ebenfalls 0). Daraus ergibt sich folgender Header:

function getComments($newsID, $parentID = 0, $i = 0)
{
    //Funktionscode
}

Zu Beginn der Funktion wird der Zähler gleich einmal mit $i++ erhöht, allerdings nur, wenn $parentID != 0 ist. Das ist deshalb wichtig, da die Unterkommentare später mit $i * 25px eingerückt werden und das erste Kommentar ja noch keine Einrückung haben soll.

Dann werden die Einträge mit newsID = $newsID und parentID = $parentID aus der Datenbank geladen und die Funktion wird erneut aufgerufen. Sollten keine Einträge vorhanden sein und $parentID den Wert 0 besitzen, wird noch ein Hinweis ausgegeben, dass keine Kommentare vorhanden sind.
Hier nun die ganze Funktion:

function getComments ($newsID, $parentID = 0, $i = 0)
{
    //$db enthält die mysqli-Verbindung zur Datenbank
    global $db
    if ($parentID != 0)
    {
        $i++
    }
    //Hier fehlt noch die Fehlerbehandlung, allerdings sollte die jeder selber hinbekommen. Ansonsten wird es dringendst Zeit sich mit den Grundlagen von PHP zu beschäftigen
    $stmt = $db->prepare('SELECT id, newsID, author, content, date FROM news_comments WHERE newsID = ? AND parentID = ?');
    $stmt->bind_param('ii', $newsID, $parentID);
    $stmt->execute();
    if ($stmt->num_rows > 0)
    {
        $stmt->bind_result($cID, $cNewsID, $cAuthor, $cContent, $cDate);
        while ($stmt->fetch())
        {
            echo '<span id="comment-author-' . $cID . '">' . $cAuthor . '</span> (am ' . $cDate . ') <a onclick="set_comment_parent(' . $cID . ')" href="#">Antworten</a>: ' . $cContent;
            getComments($newsID, $cID, $i);
        }
    }
    elseif ($parentID == 0)
    {
        echo 'Keine Kommentare vorhanden';
    }
    $stmt->close();
}

Hinzufügen von neuen Kommentaren

Hinweis: Das „normale“ hinzufügen eines Kommentars sollte eigentlich für jeden selber machbar sein und wird hier deshalb nicht behandelt. In diesem Abschnitt geht es rein um die clientseitige Setzung der parentID.

Wie der eine oder andere Aufmerksame Leser dieses Beitrags sicher schon gemerkt hat, habe ich die obige Ausgabe etwas „formatiert“. Dies ist nötig, um auf Dinge wie den Benutzernamen zuzugreifen können.

Zuerst werden ein paar neue Elemente im Formular benötigt:

  • <div id="comment_answer_to"></div>

    – Darin wird später ein kleiner Infotext angezeigt, auf welchen Benutzer geantwortet wird

  • <input name="parent_id" type="hidden" value="0" id="parent_id" />

    – Ein verstecktes Formularfeld, zur Übergabe der parentID

Nun brauchen wir nur noch die Funktion, die aufgerufen wird, wenn auf den „Antworten“-Link geklickt wird. In dieser wird die parentID gesetzt und der Benutzername auf dem man antwortet angezeigt. Wenn als Parameter 0 übergeben wird, wird die Benutzernamen-Anzeige wieder entfernt.

function set_comment_parent(id)
{
    document.getElementById('parent_id').value = id;
    document.getElementById('comment_answer_to').innerHTML = (id == 0) ? '' : 'Sie antworten auf das Kommentar von: ' + document.getElementById('comment-author-' + id).innerHTML + ' - <a href="#" onclick="set_comment_parent(0)>Zurücksetzen</a>"';
}

Damit hätten wir nun alle wichtigen Sachen für ein Kommentarsystem mit Antwortfunktion 🙂 Viel Spaß!

Comments

  1. Hi, super Tutorial für ein kleines Kommentarsystem. Ich würde jedoch keine Funktion zum holen von Kommentaren benutzen sondern eher eine Klasse. Zum Beispiel so:

    $Comment = new Comment(12); // ID als Parameter
    $Comment->getID();
    $Comment->getAuthor();
    $Comment->getMail();
    $Comment->getContent();

    und so weiter.

    Um dann alle Kommentare von einem Artikel abzufragen würde ich es so machen:

    $CommentIDs = $pdo->query(‚SELECT id FROM news_comments WHERE newsID = 12 ORDER BY time DESC‘);

    while($obj = $CommentIDs->fetch(PDO::FETCH_OBJ)) {
    try {
    $Comment = new Comment($obj->id);
    echo $Comment->getAuthor();
    // …
    }
    catch(CommentException $e) {
    // …
    }
    }

    Finde das über ne Klasse einfach schöner.

    MFG BlackY =)

  2. Ja ich sollte mir allgemein angewöhnen mehr objekt-orientiert zu Programmieren *grins*

    Bzgl der Datenbank-Abfrage: PDO ist natürlich die viel schönere Variante, allerdings nicht kompatibel mit < PHP 5.3 (sollte allerdings die meisten Webserver mittlerweile bereits erreicht haben). In meinem Fall habe ich zudem eine extremst gute Entschuldigung: Ich arbeite normalerweise immer mit einer eigenen (auf Basis einer anderen) DB-Class. Das läuft soweit, dass ich ohne schon garnicht mehr ohne arbeiten kann und mir entsprechende Teil aus dem PHP-Manual zusammenkratzen musste :3 Mfg Cheesi 🙂

  3. Jo, fürs Beispiel reicht es ja eigentlich auch, hab da glaub ich zu schnell reagiert. Wichtig ist ja die Datenbankstruktur und wie da was abgefragt wird. Auch das mit dem Javascript am Ende ist gut so dass man Antworten posten kann.

    MFG BlackY =)

Schreibe einen Kommentar

Your email address will not be published / Required fields are marked *