Ein kleiner Chat in PHP – wieder mal was für Minimalisten

Da ich mich derzeit viel im Chat in meinem Lieblings-Handarbeitsforum herumtreibe, dachte ich mir: so einen kleinen, eher spartanischen Chatroom solltest du eigentlich auch selber programmieren können, das kann so schwierig nicht sein. Bei Google gibt es -zig Beispiele, wie man so etwas angehen könnte, ich hab mich auf die Suche nach etwas Einfachem gemacht und bin hier bei php-einfach.de fündig geworden.

Ich hab allerdings ein paar Fehler bereinigt, auf PHP 7 umgeschrieben, die Ajax-Funktionalität eliminiert (warum kompliziert wenns auch einfach geht?), die MySQL-Tabelle komplett anders strukturiert, eine Teilnehmerliste hinzugefügt und sämtliche Formatierungen umgekrempelt, so dass letztendlich eine komplett umgeschmissene Logik dabei herausgekommen ist. Wie gesagt, die Grundidee stammt von php-einfach.de, und ich bedanke mich auch artig für den Denkanstoß. Aber ich denke, es ist genug kreative Eigenleistung dazugekommen, dass ich den Source hier als auf meinem Mist gewachsen einstellen kann.

Die Voraussetzungen

Viel ist nicht dran: man soll seinen Nick und seine Nachricht eingeben können, auf den Senden!-Button klicken, und dann soll im Chatfenster die Nachricht für alle sichtbar am unteren Ende des Fensters auftauchen. Ich hab noch die Uhrzeit wann die Nachricht geschrieben wurde mit dazugenommen, und protokolliere im Hintergrund auch das Datum mit, da ich in meinem Chat immer nur die Beiträge des heutigen Tages anzeigen möchte.

Aussehen tut das Ganze so:

screenshot_chat

screenshot_chat

Man kann seinen Nick eingeben (der bleibt auch nach dem Abschicken stehen), man kann seine Nachricht eingeben, und man kann auf den Senden!-Button klicken. Im Chatfenster scrollen die älteren Einträge nach oben weg, der neueste Eintrag landet immer ganz unten, und es wird noch die Uhrzeit zu jedem Beitrag angezeigt. Es werden nur die Einträge des heutigen Tages angezeigt, den Rest habe ich natürlich auch gebunkert, daraus könnte man noch ein Chat-Archiv erstellen. Rechts kriegt man noch eine Liste angezeigt, wer heute schon aller im Chat war, und das wars.

Im Hintergrund: natürlich eine MySQL-Tabelle

Die ist recht einfach strukturiert und heißt bei mir chat_daten:

chat_daten

chat_daten

Eine AutoIncrement-id als Primärschlüssel, und vier Textfelder für nick, eintrag, uhrzeit und datum, das war schon alles.

Der Sourcecode

Wir packen die Connect-Daten in eine externe Datei:

<?php 
$server    = 'localhost'; 
$user    = 'root'; 
$pass    = ''; 
$db    = 'chat'; 
$table    = 'chat_daten'; 
$conn=mysqli_connect($server, $user,$pass); 
mysqli_select_db($conn,$db); 
?>

Die Felder für Nick und Eintrag und den Senden-Button packen wir in ein Formular:

<?php  
//Config auslesen 
require_once('inc/config.php'); 
  
$heute = date("d.m.Y",time());
echo '<img src="el_logo.jpg">';
echo '<h1>Evis Chat live am '.$heute.'</h1>';

echo ' 
 <form action="index.php" method="post"> 
    <table border="0"> 
        <tr> ';
//Falls ein Nick eingegeben wurde, diesen als default in die Textbox setzen
if(!empty($_POST['nick'])){
    $akt_nick = $_POST['nick'];
}
else{
    $akt_nick='';
};
    
echo '<th>Nickname:</th><td><input type="text" name="nick" value="'.$akt_nick.'" id="textbox1"></td></tr>                 
        <tr> 
            <th>Nachricht:</th><td><input type="text" name="eintrag" value="" id="textbox">&nbsp;<input type="submit" name="eintragen" value="Senden!" id="button">&nbsp;</td> 
        </tr> 
    </table> ';

Damit man den Nick nicht immer neu eingeben muss, frage ich ab ob das Feld schon gesetzt wurde und schreibe dann den Wert als Default rein.

Dann starte ich, wenn auf den Button Senden geklickt wurde, und schreibe mir Nick, Eintrag, Datum und Uhrzeit in die Datenbank:

if(isset($_POST['eintragen'])){ 

if(empty($_POST['nick']) or empty($_POST['eintrag'])){ 
    echo '<script>alert("Bitte Nick UND Message eingeben")</script>'; 
}else{ 
    //Variablen definieren und mit "POST" Daten füllen (Mit htmlspecialchars filtern, Apostrophe maskieren..) 
    $nick = addslashes(htmlspecialchars($_POST['nick'])); 
    $eintrag = addslashes(htmlspecialchars($_POST['eintrag'])); 
    $uhrzeit = date("H:i",time());
    $datum = date("d.m.Y",time());

    
//Nick + Eintrag + datum+uhrzeit in die Datenbank schreiben 
    mysqli_query($conn,"INSERT INTO $table  
                      (nick,eintrag,uhrzeit, datum) VALUES 
                      ('$nick', '$eintrag', '$uhrzeit', '$datum')"); 
    } 

}

Falls kein Nick oder keine Nachricht eingegeben wurden, gibts einen Alert, andernfalls mache ich den Insert mit den aktuellen Daten.

Für die Ausgabe des Chats baue ich mir eine Div mit zwei darin enthaltenen Divs, weil ich Nick und Nachricht linksbündig, die Uhrzeit aber rechtsbündig ausgeben möchte. Das CSS dazu gibt es weiter unten, hier erstmal die Divs für das Chatfenster:

//alle Einträge von heute ausgeben
echo '<div id="chat_fenster" >';
        
        //Nur die Einträge von heute auslesen
          $abfrage = mysqli_query($conn,"SELECT * FROM $table WHERE datum LIKE '$datum'"); 
          while($row = mysqli_fetch_array($abfrage,MYSQLI_ASSOC)) 
          { 
            echo '<div id ="nick_und_message"><span style="color:red">'.$row['nick'].':</span><span style ="color:black">'.$row['eintrag'].'</span></div>
            <div id = "uhrzeit"><span style ="color:green">'.$row['uhrzeit'].'</span></div><br>'; 
          }
echo '</div>';

Als kleines Extra gebe ich rechts neben dem Chatfenster noch eine Liste aller Teilnehmer von heute aus:

//alle Teilnehmer von heute ausgeben
echo '<div id="teilnehmer_fenster" >';
        echo '<h2>Heute im Chat:</h2>';
        //Nur die Teilnehmer von heute auslesen
          $abfrage = mysqli_query($conn,"SELECT DISTINCT nick FROM $table WHERE datum LIKE '$datum'"); 
          while($row = mysqli_fetch_array($abfrage,MYSQLI_ASSOC)) 
          { 
            echo $row['nick'].'<br>'; 
          }
echo '</div>';

Jetzt noch ein wenig CSS-Kosmetik:

<style type="text/css"> 
    
    #textbox{ 
        width:600px; 
        border:1px solid blue; 
    } 
     
    #textbox1{ 
        width:80px; 
        border:1px solid blue; 
    }
    
    #button{ 

        border:1px solid #FF1493; 
        cursor:pointer; 
    } 
     
    #button:hover{ 
        border:1px solid #3399FF; 
    } 
    
    #nick_und_message{
        width:80%;
        float:left;
    }
    #uhrzeit {
        width:20%;
        float:right;
        text-align: right;
    }
    #chat_fenster{
        border:2px solid blue;
        width:750px; 
        height:350px; 
        padding:3px; 
        overflow: auto;
        float:left;
    }
    
    #teilnehmer_fenster{
        float:right;
        width:200px;
    }
</style>

Wichtig ist hier der Eintrag overflow:auto für das Chatfenster, der sorgt für den Scrollbalken. Damit jetzt die bereits vorhandenen Einträge nach oben wegscrollen und der letzte Eintrag immer im Chatfenster ganz unten auftaucht, noch ein kleiner Javascript-Trick:

<script>
window.onload = function()
{
//Chatfenster nach oben wegscrollen, damit immer die neuesten Einträge sichtbar sind
document.getElementById('chat_fenster').scrollTop = 9999999;
}
</script>

Man setzt einfach einen sehr hohen Wert für das Scrollen nach oben, damit ist die Liste immer nach oben weggescrollt und das Ende mit den neuesten Beiträgen bleibt im sichtbaren Bereich.

Das wars – viel Spaß beim Nachbauen! Das liesse sich natürlich noch beliebig erweitern, in einem CMS könnte man z.B. den Chat nur für eingeloggte User freischalten, dann entfällt das Abfragen des Nicks. Man könnte auch noch ein Chat-Archiv anlegen, in dem man die Beiträge der letzten Tage einsehen kann, und man könnte sonst noch allerhand Spielereien veranstalten, da kann sich jeder selber austoben. Ich lass es mal so stehen, als wirklich simple Lösung.