Aufbau eines Chatraums mit jQuery/PHP

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der Plan

In diesem Tutorial erstellen wir ein kleines Chatprogramm, das sich wirklich einfach auf jedem Server mit PHP einrichten und betreiben lässt. **Keine Datenbank erforderlich** – da der Chat in einer einfachen **Textdatei** gespeichert wird. Verwendete Technologien

  • PHP – kümmert sich um alles auf der Serverseite
    • Neue Nachrichten in die Textdatei schreiben
    • Neue Nachrichten aus der Textdatei auslesen
    • Den "Zustand" der Textdatei abrufen
    • Grundlegende Sicherheit
  • jQuery/JavaScript – kümmert sich um die Clientseite. Dies ist eine AJAX-Anwendung, was bedeutet, dass Nachrichten auf dem Bildschirm erscheinen (sowohl Ihre als auch die anderer) ohne dass die Seite neu geladen werden muss.

    • Den Server periodisch abfragen, ob neue Nachrichten gepostet wurden
    • Neue Nachrichten zum Chat hinzufügen
    • Den Chat zum neuesten Nachrichtenstand herunterscrollen
    • Benutzernamen abfragen und festlegen
    • Die Texteingabe begrenzen, um riesige, lächerliche Nachrichten zu verhindern
    • Grundlegende Sicherheit
  • Textdatei – Speichert den Chat

NICHT Der Plan

Dieses Tutorial behandelt allerlei interessante Dinge und interessante Technologien, und das Endergebnis ist definitiv ein Chatraum. Was es nicht ist, ist der funktionsreichste Chatraum der Welt. Man kann Leute nicht rauswerfen oder verbannen. Leute können potenziell denselben Namen haben. Man kann nicht alle aktuellen Mitglieder des Chats sehen. Mit anderen Worten, das ist kein IRC. Es ist nur eine lustige Demo und in vielen Situationen absolut machbar. Wenn Sie das nehmen und damit weitermachen und es funktionsreicher gestalten möchten, nur zu!

Grundlegende HTML-Struktur

<div id="page-wrap">

    <h2>jQuery/PHP Chat</h2>
    
    <p id="name-area"></p>
    
    <div id="chat-wrap"><div id="chat-area"></div></div>
    
    <form id="send-message-area">
        <p>Your message: </p>
        <textarea id="sendie" maxlength = '100'></textarea>
    </form>

</div>

Wirklich wenig Markup hier, Leute. Selbst das, was Sie oben sehen, ist zu 50 % nicht relevant für die spezifische Funktionalität dieses Tutorials. Der Seiten-Wrap dient dazu, Dinge zu zentrieren. Das doppelte Div, das mit dem Chat-Wrap und dem Chat-Bereich verwendet wird, dient nur dazu, den völlig unnötigen (aber coolen) doppelten Rahmen-Effekt im Chat-Bereich zu erzielen.

Die beiden wichtigsten Bereiche sind das Textarea mit der ID "sendie" und das Chat-Bereich-Div. JavaScript wird auf diese abzielen.

Die JavaScript-Hälfte der Engine

Wir werden unser JavaScript ein wenig objektorientiert gestalten. Wir erstellen eine "Chat"-Funktion, die Elternteil für eine Reihe anderer Funktionen für die Verwaltung von Chat-bezogenen Dingen ist.

function Chat () {
    this.update = updateChat;
    this.send = sendChat;
    this.getState = getStateOfChat;
}

updateChat fragt den Server, ob es neue Zeilen in der Textdatei gibt. Wenn ja, gibt er sie als JSON zurück und diese Funktion fügt diese neuen Zeilen dann dem Chat hinzu. sendChat wird aufgerufen, wenn eine Nachricht in das Textfeld eingegeben und Enter gedrückt wird. Die Funktion übergibt diese Daten an den Server, der damit macht, was er will. getStateOfChat fragt den Server im Grunde, wie viele Zeilen die aktuelle Textdatei hat, damit er etwas zum Vergleichen hat und weiß, wann Zeilen "neu" sind oder nicht. Diese Information wird ebenfalls als JSON zurückgegeben. Und diese Funktionen sehen aus wie

//gets the state of the chat
function getStateOfChat() {
	if(!instanse){
		instanse = true;
		$.ajax({
			type: "POST",
			url: "process.php",
			data: {'function': 'getState', 'file': file},
			dataType: "json",	
			success: function(data) {state = data.state;instanse = false;}
		});
	}	
}

//Updates the chat
function updateChat() {
	if(!instanse){
		instanse = true;
		$.ajax({
			type: "POST",
			url: "process.php",
			data: {'function': 'update','state': state,'file': file},
			dataType: "json",
			success: function(data) {
				if(data.text){
					for (var i = 0; i < data.text.length; i++) {
						$('#chat-area').append($("

						"+ data.text[i] +"

						"));
					}	
				}
				document.getElementById('chat-area').scrollTop = document.getElementById('chat-area').scrollHeight;
				instanse = false;
				state = data.state;
			}
		});
	}
	else {
		setTimeout(updateChat, 1500);
	}
}

//send the message
function sendChat(message, nickname) { 
	updateChat();
	$.ajax({
		type: "POST",
		url: "process.php",
		data: {'function': 'send','message': message,'nickname': nickname,'file': file},
		dataType: "json",
		success: function(data){
			updateChat();
		}
	});
}

Alle drei dieser Funktionen nutzen die AJAX-Fähigkeiten von jQuery und kommunizieren mit einer PHP-Datei namens process.php, die wir natürlich erstellen müssen!

Die PHP-Hälfte der Engine

Ein Teil der Daten, die mit den AJAX-Aufrufen übergeben werden, ist ein (beliebiger) Wert namens "function". Dies dient nur dazu, der PHP-Datei mitzuteilen, welche Art von Aufgabe erledigt werden soll. Daher werden wir als Erstes diesen Wert abrufen und eine switch-Anweisung einrichten, die jede mögliche Funktion abdeckt. Wir richten auch ein leeres Array ein, um Werte zu speichern, die schließlich am Ende als JSON kodiert und zurückgegeben werden.

Wenn wir versuchen, getState auszuführen, wird die Textdatei gelesen und die Anzahl der Zeilen zurückgegeben. Wenn wir update ausführen, wird die Datei gelesen und alle neuen Zeilen werden zurückgegeben. Wenn wir senden, wird die Nachricht verarbeitet und dann als neue Zeile in die Textdatei geschrieben.

<?php

    $function = $_POST['function'];
    
    $log = array();
    
    switch($function) {
    
       case('getState'):
           if (file_exists('chat.txt')) {
               $lines = file('chat.txt');
           }
           $log['state'] = count($lines); 
           break;  
      
       case('update'):
          $state = $_POST['state'];
          if (file_exists('chat.txt')) {
             $lines = file('chat.txt');
          }
          $count =  count($lines);
          if ($state == $count){
             $log['state'] = $state;
             $log['text'] = false;
          } else {
             $text= array();
             $log['state'] = $state + count($lines) - $state;
             foreach ($lines as $line_num => $line) {
                 if ($line_num >= $state){
                       $text[] =  $line = str_replace("\n", "", $line);
                 }
             }
             $log['text'] = $text; 
          }
            
          break;
       
       case('send'):
       	 $nickname = htmlentities(strip_tags($_POST['nickname']));
	     $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
	     $message = htmlentities(strip_tags($_POST['message']));
	     if (($message) != "\n") {
	       if (preg_match($reg_exUrl, $message, $url)) {
	          $message = preg_replace($reg_exUrl, '<a href="'.$url[0].'" target="_blank">'.$url[0].'</a>', $message);
	       } 
	          fwrite(fopen('chat.txt', 'a'), "<span>". $nickname . "</span>" . $message = str_replace("\n", " ", $message) . "\n"); 
	     }
         break;
    }
    echo json_encode($log);
?>

Das Ganze in Gang bringen

Wir müssen etwas JavaScript tun, um diese Party zu starten. Wir müssen jQuery laden, die "Engine" laden und dann ein paar schnelle Funktionen ausführen, um den Namen der Chatteilnehmer für den Beitritt zum Chat zu ermitteln.

Lassen Sie uns gleich die Dinge für die Begrenzung der Länge des eingegebenen Textes und das Senden des Textes mit einem Tastendruck einfügen.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="chat.js"></script>
<script>

  // ask user for name with popup prompt    
  var name = prompt("Enter your chat name:", "Guest");
 
  // default name is 'Guest'
  if (!name || name === ' ') {
    name = "Guest";  
  }
  
  // strip tags
  name = name.replace(/(<([^>]+)>)/ig,"");
  
  // display name on page
  $("#name-area").html("You are: <span>" + name + "</span>");
  
  // kick off chat
  var chat =  new Chat();

  $(function() {
  
     chat.getState(); 
     
     // watch textarea for key presses
     $("#sendie").keydown(function(event) {  
     
         var key = event.which;  
   
         //all keys including return.  
         if (key >= 33) {
           
             var maxLength = $(this).attr("maxlength");  
             var length = this.value.length;  
             
             // don't allow new content if length is maxed out
             if (length >= maxLength) {  
                 event.preventDefault();  
             }  
         }  
                                                                                                     });
     // watch textarea for release of key press
     $('#sendie').keyup(function(e) {  
                
        if (e.keyCode == 13) { 
        
              var text = $(this).val();
              var maxLength = $(this).attr("maxlength");  
              var length = text.length; 
               
              // send 
              if (length <= maxLength + 1) { 
                chat.send(text, name);  
                $(this).val("");
              } else {
                $(this).val(text.substring(0, maxLength));
              }  
        }
     });
  });
</script>

Periodisches Prüfen auf neue Nachrichten

Wir müssen die "update"-Funktion unseres Chats verwenden, um die Textdatei auf neue Nachrichten abzufragen und sie bei Bedarf anzuhängen. Dazu müssen wir diese update-Funktion regelmäßig aufrufen, und wir verwenden dafür die setInterval()-Funktion von JavaScript.

<body onload="setInterval('chat.update()', 1000)">

Die Grundlagen

Dateien herunterladen

Hinweis: Denken Sie daran, dass dies PHP-basiert ist, sodass Sie die Dateien nicht einfach herunterladen und lokal öffnen und erwarten können, dass es funktioniert, es sei denn, Sie betreiben einen lokalen PHP-Server. Denken Sie auch daran, die Dateiberechtigungen der Datei chat.txt so zu ändern, dass sie beim Hochladen auf Ihren eigenen Testort vom Server beschreibbar sind.