
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
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.
Schöner Artikel/Skript.
Nur ein kleiner Tippfehler, Chris. Beim 'Hinweis'
„Denken Sie daran, dass dies PHP-basiert ist, sodass Sie können“
Ich glaube, Sie meinen... . .
„Denken Sie daran, dass dies PHP-basiert ist, sodass Sie nicht können“
Ich habe an etwas Ähnlichem gearbeitet. Allerdings nutze ich Long Polling (stellen Sie eine Verbindung zum Server her und warten Sie auf eine Antwort) anstatt jede Sekunde nach einem Update zu fragen.
Ich habe ein einfaches Screencast erstellt, das die Grundlagen des Long Pollings zeigt: http://screenr.com/SNH
Hey Stephen, tolle Idee, schreib mir eine E-Mail und wir können über das Long Polling zusammenarbeiten.
Ich sollte mir das ansehen, ich suche schon seit einiger Zeit nach Informationen über Long Polling.
@Chris: schöner & origineller Artikel ;)
Nur eine Sache
Wäre es besser und schneller (meiner Meinung nach), wenn es im $(function() {}); wäre, nicht wahr?
$(function() {//anderer Kram
setInterval(function() { //verwende eine Funktion, keine Zeichenkettechat.update();
}, 1000);
});
Feuere das setInterval vor dem onload-Ereignis ab und starte nicht den JS-Compiler/Kompilator (ich bin mir nicht sicher, wie das richtige Wort auf Englisch ist).
Tolle Idee. Natürlich ist es im Moment eher ein funktionelles Konzept, daher macht es keinen Sinn, sich mit kleinen störenden Details zu befassen, da jede reale Implementierung sowieso etwas Pflege benötigen würde.
Aber prinzipiell gut gemacht.
Ich habe es in IE getestet und es scheint zu fehlschlagen. Nachricht kann nicht gesendet werden und scheinbar wird nicht aktualisiert.
Tolles Beispiel. Dies könnte jedoch Ihre Datenbank überlasten, also denken Sie daran, dieses Skript auf einer separaten Datenbank zu verwenden, die nicht für andere verwendet wird.
Erinnert mich sehr an "phpFreeChat" (das viel mehr Funktionalität hat), aber dieses hier sieht einfach schlanker aus und verwendet jQuery.
Gute Arbeit, Leute!
Ups – egal! Ich habe später gesehen, dass keine Datenbankaufrufe erfolgen, sondern in eine Datei geschrieben wird. Toll!
Die Demo wird bereits getrollt.
Das ist sie tatsächlich... Traurige, traurige Situation.
Ja, das habe ich mir gedacht. Das ist eine dieser Situationen, in denen eine kleine Handvoll Idioten eine perfekt gute Demo ruinieren können.
Na ja. Ich werde ihre IPs veröffentlichen.
Es ist im Moment ohnehin nicht wirklich als Treffpunkt gedacht, sondern nur als Demo der Funktionalität.
Schön gesagt... :)
Das ist wirklich gut gemacht! Ich bin froh, dass es auch aktualisiert wird, um neue Dinge hinzuzufügen.
Und ich muss zustimmen, einige Leute spammen dort viel….
Auf jeden Fall danke fürs Lehren.
Danke Chris und Kenrick!
Wenn Sie planen, dies über das einfache AJAX-Erlebnis hinaus zu skalieren, sollten Sie sich mit einer Technologie namens Comet befassen. Sie ist hervorragend geeignet, um "Live"-Anwendungen wie Chat mit AJAX durch latenzarme Anfragen und serverseitige Push-Nachrichten zu verwalten.
http://www.cometd.org/
Es ist eine wirklich coole Demo, aber UTF-8-Zeichen scheinen ein wenig durcheinander zu geraten. Vielleicht muss die Kodierung vor der Ausgabe erfolgen.
Ja, UTF-Zeilen gehen kaputt
Ich liebe die Seite, das ist mein erster Kommentar, und Sie erkennen wahrscheinlich einige Codes von meiner Seite. Ich finde das sehr faszinierend und nützlich, aber was passiert mit tollen Funden wie diesen, sobald Sie Google Waves in Ihren Blog einbetten können? Ich hoffe, dass nicht alle Leute davon gelangweilt sind, bevor sie Mainstream werden.
Gut gemacht :D
Gute Arbeit, danke Chris & Kenrick :)
Verwenden Sie COMET anstelle des periodischen Prüfens auf neue Nachrichten. Es ist schneller und flüssiger (wie normaler Chat). Es ist zwar komplizierter, aber nicht viel :) Die Idee ist, eine Endlosschleife in PHP auf dem Server zu erstellen, was zu einer persistenten Browser-Server-Verbindung führt. Keine Sorge, wenn der Client die Verbindung trennt, wird PHP die Schleife unterbrechen.
erstaunliches Tutorial…
Ich werde es auf meiner Facebook-Seite teilen..
Danke CSS Trick.
Wenn Sie nach oben scrollen, springt es beim Aktualisieren nach unten…
Ich habe eine kleine Frage…
Der Chat wird alle 1000 Millisekunden aktualisiert, richtig..
aber kann ich wissen, dass der Chat alle 1 Sekunde **ODER** nach der Antwort der letzten Anfrage aktualisiert wird?
Ich glaube, Sie wissen, was ich meine!!
Hallo! Ich habe das noch nicht gelesen, aber sobald ich die Überschrift sah, war ich sofort begeistert und wollte sagen, was für eine erstaunliche Idee es war, ein Tutorial zu diesem Thema hinzuzufügen.
Es ist so eine süße Idee. Sie haben so großartige Ideen für Themen. Sie müssen sehr beschäftigt sein!
Ich mag es wirklich, wie Sie so viele verschiedene Sprachen und Techniken verwenden, da es uns allen ein umfassenderes Verständnis von Webdesign/Entwicklung vermittelt.
Hallo Chris,
Langjähriger Leser, erster Kommentator (musste es sagen!). Ich wollte fragen, ob Sie Ratschläge zur Erweiterbarkeit haben. Ich möchte dieses Konzept vom einfachen, einzelnen Raum-Chat in etwas Komplexeres umwandeln, das in separate Textdateien für zukünftige Referenz und Datenschutz schreiben könnte. Ist das möglich?
Vielen Dank,
Elliot
Ja, Elliot, indem Sie einfach den Dateinamen in der Datei process.php ändern, können Sie in eine andere Datei schreiben, also Chaträume. Und das werde ich für 2.0 tun.
Hallo Chris,
sehr schönes Chatraum-Ding! Ich frage mich, werden Sie es auf Ihrer Website als Treffpunkt implementieren? Denn wenn ja, wäre es toll, ein paar Räume zu haben, wie einen CSS-Raum/ PHP-Raum etc... damit wir Dinge spontan besprechen können?
Ich weiß nicht, ich finde einfach, dass Sie das sehr gut gemacht haben und es wäre schön, es zu einem vollständigen Feature zu machen. Ich habe keine Ahnung, wie viel zusätzliche Arbeit das bedeuten würde, daher würde ich verstehen, wenn es eine Mission wäre.
Wow. Das ist sehr großartig, und ich könnte das definitiv tun.
Ich würde auch gerne ein erweitertes Tutorial sehen, wie man das verbessert, z. B. nicht mehrere Instanzen desselben Benutzernamens zuzulassen und das Bannen. Plus Moderatoren.
Unterstützt keine türkischen Zeichen?
Wie würde man die Zeit einfügen, nicht die IP?
großartig!!! @kenrick, ich warte schon seit meiner Demo darauf!!! Danke Chris und Kenrick!!!! Ich sprang auf und verletzte mich buchstäblich, als ich diesen Artikel endlich gepostet sah!!!
Hallo Chris,
Ich habe viel Spaß und lerne viel mit all den Screencasts auf Ihrer Website und dies ist ein sehr schönes Konzept einer webbasierten Chat-Anwendung.
Nur eine Idee. Ich denke, Sie sollten eine Sperrlogik implementieren, insbesondere für die Dateibehandlung, um die Anwendung Thread-sicher zu machen.
Hallo Chris!
Das ist eine ziemlich nette Demo. Gutes Tutorial für einen grundlegenden und funktionalen Chat.
Nette Demo!
Was ist der Live-Hilfe-Chat, der auf http://www.psd2xhtml.com/chat.html verwendet wird? Es sieht so aus, als wären Mootools, Ajax und HTML verwendet worden, und es ist ziemlich gut, aber ich kann den Namen nicht finden.
Vielen Dank.
Schönes Tut, aber funktioniert nicht in IE!
Ist das überhaupt nötig? Für einen doppelten Rahmen, könnte man nicht einfach border: 3px double black; oder was auch immer verwenden?
Um ehrlich zu sein, ich habe vergessen/nicht gewusst, dass es überhaupt eine "double"-Eigenschaft für Rahmen gab. Ich werde damit mehr experimentieren müssen. Es scheint, dass dies sehr selten verwendet wird, daher frage ich mich, ob es Probleme damit gibt.
Fantastisches kleines Skript hier! Zu schade, dass es nur UTF-8-Zeichen frisst... selbst mit einem anderen Zeichensatz wird etwas mit fremden Zeichen wie æ, ø und å durcheinandergebracht :(
Ja
Ich habe es gelernt und gut verstanden
Es ist einfach
Haben Sie eine Beispielseite, Dude... Besser zeigen Sie es, bevor jemand es selbst versucht. Und danke... posten Sie weiter
Und Grüße aus Indonesien
Entschuldigung, Bro... Ich sehe kein "Demo anzeigen" hier... Ich habe es versucht... und es ist einfach zu benutzen... Aber was ist mit der Datenbank? Sie wächst und wächst hm.... Und wie können wir ältere Nachrichten löschen... bevor sie auf dem Server gebündelt werden?
Hallo Chris.
Netter Chat, aber dieses Skript funktioniert nicht richtig mit UTF-8. Ich versuche, auf Georgisch zu schreiben, und das ist mein Ergebnis
გამარჯობა -> verwandelt in -> á
Ich arbeite gerade an einer Implementierung eines GMail-Chat-Klons, der Push über ein Forever-Frame nutzt. Ich habe eine Version erstellt, die Short Pulls mit einfachem Javascript verwendet, war aber nicht so beeindruckt von der Reaktionsfähigkeit des GMail Push Chat-Methode.
Ich werde es posten, wenn / falls ich jemals fertig bin (sollte aber bald genug sein, hofft man).
Mein Problem war die Erstellung dieses Forever-Frames (ständig ladendes iframe), der ausgehende XMLHttpRequests nicht am Senden hindert (d. h. Ihre Nachrichten, die auf den Benutzer zurückantworten). Wenn jemand einen sicheren Weg kennt, dies zu tun, lassen Sie es mich wissen, sonst werde ich weiter daran basteln, :D.
– Dan
$message = htmlentities(strip_tags($_POST['message']));
htmlentities – macht UTF-Zeichenkette unlesbar…
Ich mochte Ihr Beispiel oben auf der Seite mit den beiden Bots, die miteinander reden :D :D :D cool :P
Hey. Die Demo funktioniert nicht. :(
Sollte behoben sein. Keine Ahnung, was da schiefgelaufen ist.
Das ist sehr interessant, da ich plane, eine Website für mich selbst zu erstellen, und ich einen sehr interessanten Live-Chatroom benötigen werde, und ich werde versuchen, den Code nicht zu kopieren und zu sehen, wie Sie es gemacht haben... danke
Es ist ein großartiges System. Eine Frage!! Wie kann ich die gesendeten Nachrichten dauerhaft auf der Seite behalten? Im Moment werden sie beim Aktualisieren der Seite für den nächsten neuen Gast gelöscht. Ich möchte, dass sie für den nächsten Gast, der die Seite betritt, bestehen bleiben und manuell aus der .txt gelöscht werden.
Ich freue mich auf Ihre Antwort!!!!!!!!!! – Ich schätze Ihre Hilfe sehr!!!!! Danke!
Das ist fantastische Arbeit, ich habe es auf meiner Website hochgeladen, aber keine Aktion,
Zeigen Sie mir, wie ich chat.txt beschreibbar mache!
Ich habe die Dateien heruntergeladen und es funktioniert großartig!!! Ich benutze diese Web-Chat-Anwendung, um Cross-Site-Scripting Kollegen zu demonstrieren. Ich sehe, dass index.php der Befehl: name:=name.replace Tags entfernt und auch in process.php im 'send'-Fall viele Codes verwendet werden, um Tags zu entfernen. Aber wenn ich viele davon entferne (auskommentiere), entdecke ich, dass ein Statement in die chat.txt Datei geschrieben werden kann, aber es wird nicht im Chatfenster angezeigt. Wie kann ich das Statement so anzeigen, dass ein Benutzer auf den Link klicken und auf eine andere Website umgeleitet werden kann. Bitte denken Sie daran, dass ich dies zur Demonstration von Cross-Site-Scripting verwende. Danke, rick1235
Ich versuche, ein HREF-Statement im Chatfenster erscheinen zu lassen, damit ich Cross-Site-Scripting demonstrieren kann. Ich kann das HREF-Statement in die chat.txt Datei schreiben, aber es erscheint nicht im Chatfenster.
Für den Fall, dass dies nicht offensichtlich ist, möchte ich jemandem anders Zeit sparen: Wenn Sie dies über https verwenden möchten, ändern Sie die src-Referenz des Skript-Tags ebenfalls auf https.
(Das heißt, wenn Sie es mit der Sicherheit wirklich ernst meinen, sollten Sie sich sowieso Version 2 des Chats ansehen...)
Vielen Dank für diesen Beitrag!
Hallo! wunderbarer Chat. Aber ich habe ein Problem mit dem russischen Kyrillisch-Linux-System. Wörter werden angezeigt als „Вл Ð ° Ð ¾“ oder „null“, was mache ich? Das System unter Windows – die Wörter werden korrekt angezeigt.
PS Entschuldigung für mein Englisch, ich übersetze mit Google Übersetzer
HI…. Kann mir jemand hierbei helfen? Ich mache ein Chat-Konzept, bei dem das Konzept "tippt gerade" nicht funktioniert….. Ich habe setInterval ausprobiert, aber das funktioniert nicht…..
Wir haben auf einem Linux-Server bereitgestellt, es funktioniert dort nicht und lokal funktioniert es gut
dreamin.in/jchat
Ich kann nicht herausfinden, was schief gelaufen ist
Zum Beheben von Charsets
Wie erstelle ich einen Button zum Senden von Nachrichten?