Programujeme chat s dynamickým načítáním
Ve svém prvním článku jsem psal o dynamickém načítání dat na www stránce. V tomto článku bych chtěl ukázat, jak se dá toto načítání použít například u velice zjednodušeného chatu.
K tomuto chatu uvedu i popsaný skript na validaci formuláře, která je u tohoto chatu také použita.
14.3.2013 10:00 |
Vladimír Macháček
| Články autora
| přečteno 12643×
Úvodem
Nejdříve bych se rád zmínil o tom, že tento chat, na kterém budu demonstrovat dynamické načítání dat, je jen praktická ukázka a aby jej bylo možné umístit na stránky, muselo by se ještě pořešit zabezpečení a provést pár úprav. Tím ale nechci říci, že chat o kterém budu dále psát je nefunkční.
Co bude chat umět
Chat o kterém píšu bude pracovat pouze s daty z databáze. Uvádím to proto, že data z chatu, jako například zprávy, je možné načítát ze souboru i je do něj ukládat. Tento jednoduchý chat bude umět pravidelně zobrazovat nové zprávy, online uživatele a mazat neaktivní uživatele. Dále bude mít validaci formuláře, kterou si nebudeme stahovat, ale vytvoříme si ji. Validace bude zahrnovat zobrazování zbývajích znaků, které je ještě možno napsat do jména/zprávy a obarvení inputů podle splněné nebo nesplněné podmínky.
Ukázky z chatu
Jak to bude fungovat
Při načtení dokumentu se provede funkce rf();. Nejdříve se u chatu zobrazí vstupní adresář. Ten zahrnuje input pro vložení přezdívky. Jakmile si uživatel zvolí přezdívku a klikne na tlačítko vstoupit, skryje se vstupní formulář, spustí se interval funkce rf(); a zobrazí se mu právě probíhající konverzace na chatu, online uživatelé a formulář pro psaní zpráv. Při každé odeslané zprávě se provede aktualizace času poslední akce tohoto uživatele a kontrola, jestli nebyl uživatel odhlášen kvůli nečinnosti. Pokud byl odhlášen, skript ho vrátí na úvodní stránku.
Začínáme
Na začátek si jako v předchozím článku stáhneme knihovnu jQuery a vytvoříme adresáře se soubory ze kterých se bude náš chat skládat. Budou to tyto soubory:
- chat.php
- js
- css
- php
- config.php
- send.php
- messages.php
- users.php
- login.php
- logout.php
- cldb.php
Tabulky v databázi
Databáze, ve které budou uloženy tyto dvě tabulky se jmenuje test a porovnávánání v této db je nastaveno na UTF_8_czech_ci. K tomuto příkladu bude potřeba vytvořit 2 tabulky. Jedna bude chatusers a druhá chatmsg. V tabulce chatusers budou následující sloupce:
- id-(INT)
- name-(VARCHAR) omezení počtu znaků na 20
- time-(INT)
Tabulka chatmsg bude vypadat takto:
- id-(INT)
- name-(VARCHAR) max. počet znaků bude 20
- text-(VARCHAR) omezení počtu znaků na 500
- time-(TIME)
Skript pro vytvoření tabulek
<?php
$dblogin='';//Přihlašovací jméno
$dbpassword='';//Heslo
$db = new PDO('mysql:host=localhost;dbname=test;charset=UTF-8', $dblogin, $dbpassword);//Připojení k databázi
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Nastavení řízení chyb
try {
$stmt=$db->query('CREATE TABLE chatusers (id INT NOT NULL AUTO_INCREMENT ,name VARCHAR( 20 ) NOT NULL ,
time INT NOT NULL ,PRIMARY KEY ( id ))');
echo 'Tabulka chatusers byla úspěšně vytvořena!<br/>';
} catch(PDOException $e) {
echo 'Nastala chyba:'.$e;
};
try {
$stmt=$db->query('CREATE TABLE chatmsg (id INT NOT NULL AUTO_INCREMENT ,name VARCHAR( 20 ) NOT NULL ,
text VARCHAR( 500 ) NOT NULL ,time TIME NOT NULL ,PRIMARY KEY ( id ))');
echo '<br/>Tabulka chatmsg byla úspěšně vytvořena!';
} catch(PDOException $e) {
echo 'Nastala chyba'.$e;
}
?>
Chat.php
V tomto souboru bude hlavní struktura chatu. Chat bude obsahovat 2 formuláře. Jeden bude vstupní, ten bude pro přezdívku a druhý bude pro komentář. Formuláře si budou vzájemně prohazovat pozice a to tak, že se jim budou měnit hodnoty z display:none na display:block a opačně.
Struktura tohoto souboru je následující:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/chat.js"></script>
<link rel="stylesheet" href="css/chat.css" />
<title>Chat</title>
</head>
<body>
<div id="chat">
<div id="chenter">
<h3>Chat</h3>
<form method="post" name="cheform" id="cheform">
<label for="chnick">Nick:</label><input type="text" name="chnick" id="chnick" placeholder="3-20 znaků" />
<input type="button" id="ech" disabled="disabled" onclick="eCh();" value="Vstoupit" />
Zbývající znaky:<span id="nlch"></span>
<span id="errors"></span>
</form>
</div>
<div id="chroom">
<div id="chmessages">
<?php
include('php/messages.php');
?>
</div>
<div id="chusers">
<?php
include('php/users.php');
?>
</div>
<div id="chbottom">
<form method="post" name="chform" id="chform">
<label for="chmessage">Zpráva:<br /><span id="mlch"></span></label> <textarea placeholder="3-300 znaků." name="chmessage" id="chmessage"></textarea>
<input type="button" id="chsm" disabled="disabled" onclick="sChM();" value="Odeslat"/>
</form>
</div>
</div>
</div>
</body>
</html>
Chat.css
V tomto souboru je css stylování chatu. Je na vás, jaký vzhled si vytvoříte. Důležité jsou pouze následující hodnoty:
#chroom {
display: none;
}
#chenter {
display:block;
}
#chusers {
overflow:auto;
}
#chmessages {
overflow: auto;
}
Chat.js
Na tomto souboru to vše stojí. Jsou zde vytvořeny funkce pro vstup do chatu, odeslání zpráv, refreshování zpráv a uživatelů a validace formuláře. Každý řádek skriptu je pro jednoduchost, přehlednost a lepší pochopení popsán.
// JavaScript Document
$(document).ready(function(){//Načtení dokumentu
rf();//Provedení refreshe zpráv a uživatelů v chatu
chControll();//Provedení kontroly formulářů
$('#chnick').keyup(chControll);//Začátek zaznamenávání akce kláves
$('#chmessage').keyup(chControll);//Totéž
});
function eCh() {//Funkce enter chat(eCh)
var nl=$('#chnick').val().length;
if(nl>=3) {
$('#chenter').css('display','none');
$('#chroom').css('display','block');
$.post('php/login.php',{nick:cheform.chnick.value},
function(output) {//Funkce která vypíše vrácená data
if(output){//Pokud byla nějaká data vrácena
$('#chenter').css('display','block');//Změna displeje z none na block
$('#chroom').css('display','none');//Změna displeje z block na none
$('#errors').html(output);//#chenter tyto data vypíše
} else {
$('#chform').css('display','block');//Pokud ne, #chform se nastaví na display:block
}
}
);
setInterval(rf,2500);//Nastavení intervalu refreshe
} else {
$('#errors').html('Váš nick je příliš krátký');//Pokud je Nick příliš krátký, vypiš varovaní
}
};
function sChM() {//Funkce send chat message(sChM)
var ml=$('#chmessage').val().length;
var nl=$('#chnick').val().length;
if(ml>=3 && nl>=3) {
$.post('php/send.php',{nick:cheform.chnick.value, message:chform.chmessage.value});
$.post('php/logout.php',{nick:cheform.chnick.value},//Zjisti, jestli nebyl uživatel odhlášen z důvodu neaktivity
function(output){
if(output) {
$('#chenter').css('display','block');//Změna displeje z none na block
$('#chroom').css('display','none');//Změna displeje z block na none
$('#errors').html(output);//Vypiš output
};
}
);
} else {
$('#chbottom').append('<span class="chlwarning">Vaše zpráva je příliš krátká.</span>');
}
};
function rf() {//Funkce refreshování zpráv a uživatelů
$('#chmessages').load('php/messages.php');//Načtení požadovaného souboru
$('#chusers').load('php/users.php');//Totéž
};
function chControll() {//Funkce pro kontrolu formuláře
var lname=$('#chnick').val().length;//Počet znaků #chnick
var lmessage=$('#chmessage').val().length;//Počet znaků v #chmessage
var name=$('#chnick').val();//Získání hodnoty #chnick
var message=$('#chmessage').val();//Získání hodnoty #chmessage
var nsubstr=name.substring(0,20);//Zkrácení počtu znaků name substring(nsubstr) na maximálních 20
var msubstr=message.substring(0,500);//Zkrácení počtu znaků message substring(msubstr) na maximálních 500
var nchleft=20-lname;//Zjištění zbývajících počtu znaků v #chnick
var mchleft=500-lmessage;//Zjištění zbývajícího počtu znaků v #chmessage
$('#nlch').html(nchleft);//Vložení zbývajícíh počtu znaků do nick left characters(nlch)
$('#mlch').html(mchleft);//Vložení zbývajícího počtu znaků do message left characters(mlch)
$('#chnick').val(nsubstr);//Vložení omezeného počtu znaků do #chnick
$('#chmessage').val(msubstr);//Vložení omezeného počtu znaků do #chmessage
if(lname>=3 && lmessage>=3) {//Pokud jsou splněny podmínky lname a lmessage
$('#chsm').removeAttr('disabled');//Odeber atribut disable u tlačítka chat send message(chsm)
} else {//Pokud pomínky nejsou splněny
$('#chsm').attr('disabled','disabled');//Přidej atribut disabled k tlačítku #chsm
};
if(lname<3) {//Pokud je splěna podmínka
$('#chnick').css('border','3px solid #F00');//Vytvoř červený rámeček okolo #chnick
$('#ech').attr('disabled','disabled');//Přidej atribut disabled ke tlačítku enter chat(ech)
} else {//Pokud pomínka není splněna
$('#chnick').css('border','3px solid #00ff00');//Změn barvu rámečku na zelenou
$('#ech').removeAttr('disabled');//Odeber atribut disabled
};
if(lmessage<3) {//Pokud je podmínka splněna
$('#chmessage').css('border','3px solid #F00');//Vytvoř červený rámeček kolem zprávy
} else {//Pokud podmínka není splněna
$('#chmessage').css('border','3px solid #00ff00');//Změn barvu rámečku na zelenou
};
};
Validace formuláře:Validaci formuláře má na starost funkce chControll();. Jsou v ní zaznamenávány hodnoty z inputů #chnick a #chmessage. U nich se měří počet znaků a ten je vkládán na určitá místa. Konkrétně u zprávy to je #mlch a u přezdívky (nicku) #nlch. Obarvení rámečku je zelené pokud je v inputech více znaků než 3. Červeně pokud není. Překročení maximálního počtu znaků je chráněno pomocí nchleft a mchleft. Hodnoty těchto dvou proměnných jsou vkládány na místo základního textu.
Config.php
V tomto souboru bude pouze jméno databáze, přistupovací jméno a heslo, připojení k databázi a proměnná $rewrite.
<?php
$dbname='';//Jméno databáze
$dblogin='';//Přihlašovací jméno
$dbpassword='';//Heslo
$db = new PDO('mysql:host=localhost;dbname=test;charset=UTF-8', $dblogin, $dbpassword);//Připojení k databázi
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Nastavení řízení chyb
$rewrite=array('<'=>'<', '&'=>'&')//Změna prvku v poli
?>
Login.php
Do tohoto souboru se odešle přezdívka, kterou si uživatel zvolil. Zkontroluje se, zdali již přezdívka neexistuje. Pokud ne, žádná data se nevrátí a uživateli se zobrazí formulář pro psaní zpráv a do tabulky se vloží jeho jméno. Pokud se ale jméno již v tabulce nachází, uživatel bude vrácen na vstupní formulář a bude požádán o zvolení jiné přezdívky.
<?php
include('config.php');//Načti soubor
$nick=substr(strip_tags(StrTr($_POST['nick'],$rewrite)),0,20);
$time=Time();
try {
$stmt = $db->prepare("SELECT * FROM `$dbname`.`chatusers` WHERE `name`=?");//Připrav dotaz
$stmt ->bindParam(1, $nick, PDO::PARAM_STR);//Oddělení parametru od hlavního programu
$stmt->execute();//Provedení dotazu
if($stmt->rowCount()==NULL) {//Pokud se počet vrácených řádků rovná 0
$stmt = $db->prepare("INSERT INTO `$dbname`.`chatusers` (`id` ,`name` ,`time`)VALUES (NULL, ?, ?)");//Vlož do tabulky nick
$stmt ->bindParam(1, $nick, PDO::PARAM_STR);//Oddělení parametru od hlavního programu
$stmt ->bindParam(2, $time, PDO::PARAM_INT);//Totéž
$stmt->execute();//Provedení dotazu
} else {//Pokud se řádek rovná 1
echo 'Toto jméno už existuje, musíte zvolit jiné.';//Vypiš varování
}
} catch (PDOException $e){//Pokud nastala chyba
exit("Nepodařilo se přihlásit.".$e->getMessage());//Vypiš chybu a hlášku
}
?>
Logout.php
Skript v tomto souboru zajišťuje, aby uživatel, který byl již odhlášen pro neaktivitu, nemohl pokračovat v konverzaci a musel se znovu přihlásit.
<?php
include('config.php');//Načti soubor config.php
$nick=substr(strip_tags(StrTr($_POST['nick'],$rewrite)),0,20);//Zkrať počet znaků, odstraň tagy a nahraď "<" za <
try {
$stmt = $db->prepare("SELECT * FROM `$dbname`.`chatusers` WHERE `name`=?");//Připravení dotazu
$stmt ->bindParam(1, $nick, PDO::PARAM_STR);//Rozdělení parametru od hl. programu
$stmt->execute();//Provedení dotazu
if($stmt->rowCount()==NULL) echo 'Byly jste odhlášeni pro neaktivitu.';//Pokud nebyl nalezen řádek se jménem vypiš zprávu
} catch (PDOException $e) {//Pokud nastala chyba
exit("Nepodařilo se vypsat zprávy.".$e->getMessage());//Vypiš chybu a hlášku
}
?>
Users.php
Zde se získají všechny řádky v tabulce chusers a vypíší se. Jeden řádek = jeden uživatel.
<?php
include('config.php');//Načti soubor
try {
$stmt = $db->query("SELECT * FROM `$dbname`.`chatusers` ");//Dotaz do db
while ($row = $stmt->fetch()) {//Vypsání dat
echo '<div class="user">'.$row['name'].'</div>';
}
} catch (PDOException $e) {//Pokud nastala chyba
exit("Nepodařilo se vypsat uživatele.".$e->getMessage());//Vypiš chybu a hlášku
}
?>
Messages.php
Následujících pár řádků skriptu zajišťuje získání všech zpráv z databáze, seřazení a následný výpis.
<?php
include('config.php');//Načti soubor config.php
try {
$stmt = $db->query("SELECT * FROM `$dbname`.`chatmsg` ORDER BY `time`");//Dotaz do db
while ($row = $stmt->fetch()) {//Vypsání dat podle potřeby
echo '<div class="msg"><div class="msginf"><span class="msgnick">'.$row['name'].'</span> <span class="msgdate">'.$row['time'].'</span></div><div class="msgtext">'.$row['text'].'</div></div>';
}
} catch (Exception $e) {//Pokud nastala chyba
exit("Nepodařilo se vypsat zprávy.".$e->getMessage());//Vypiš chybu a hlášku
}
?>
Send.php
V tomto skriptu jsou 2 try-catch bloky. Uvnitř prvního se provádí odesílání dat do databáze a ve druhém updatovaní času poslední akce uživatele. Čas se updatuje proto aby skript, který bude spouštěn CRONem, mohl smazat offline uživatele, kteří byly po určitou dobu neaktivni. Nastavení této hodnoty je na vás. Je dobré to přizpůsobit minimálnímu časovému intervalu spouštění CRONu. Tak zajistíte, že bude seznam online uživatelů pořád a co nejvíce aktuální.
<?php
include('config.php');//Načti soubor config.php
$time=Time();
$nick=substr(strip_tags(StrTr($_POST['nick'],$rewrite)),0,20);//Odstraň tagy, přepiš "<" na entitu < a zkrať počet znaků
$message=substr(strip_tags(StrTr($_POST['message'],$rewrite)),0,500);//Totéž
$strftime=StrFTime("%H:%M:%S");//Získání času typu 14:22:36
try {
$stmt = $db->prepare("INSERT INTO `$dbname`.`chatmsg` (`id` ,`name` ,`text` ,`time`)VALUES (NULL, ?, ?, ?)");//Připravení dotazu
$stmt ->bindParam(1, $nick, PDO::PARAM_STR);//Rozdělení parametru od hlavního programu
$stmt ->bindParam(2, $message, PDO::PARAM_STR);//Totéž
$stmt ->bindParam(3, $strftime, PDO::PARAM_STR);//Totéž
$stmt->execute();//Proveď dotaz
} catch (PDOException $e){//Pokud se dotaz nezdařil
exit("Zprávu se nepodařilo odeslat.".$e->getMessage());//Vypiš zprávu a chybovou hlášku
}
try {//Zde se provede update času poslední akce tohoto uživatele
$stmt = $db->prepare("UPDATE `$dbname`.`chatusers` SET `time` =? WHERE `chatusers`.`name` ==?");//Připravení dotazu
$stmt ->bindParam(1, $strftime, PDO::PARAM_INT);//Rozdělení parametru od hlavního programu
$stmt ->bindParam(2, $nick, PDO::PARAM_STR);//Totéž
$stmt->execute();//Proveď dotaz
} catch (PDOException $e){//Pokud se dotaz nezdařil
exit("Nepodařilo se aktualizovat váš stav.".$e->getMessage());//Vypiš zprávu a chybovou hlášku
}
?>
Mazání neaktivních uživatelů
Tento skript musí být spouštěn CRONem. Záleží na vás, jaký interval nastavíte. Pokud nastavíte například na 5 minut, tak musíte u $timeout nastavit na místo hodnoty 3600 jen 300.
<?php
$dbname='test';//Jméno databáze
$dblogin='';//Přihlašovací jméno
$dbpassword='';//Heslo
$db = new PDO('mysql:host=localhost;dbname=test;charset=UTF-8', $dblogin, $dbpassword);//Připojení k databázi
$time=Time();
$timeout=$time-3600;
$stmt = $db->query("DELETE FROM `$dbname`.`chatusers` WHERE `chatusers`.`time < $timeout;");//Dotaz do db
$stmt = $db->query("SELECT * FROM `$dbname`.`chatmsg`");
$nrows=$stmt->rowCount();
if($nrows>=80) {//Pokud je počet zpráv větší než 80
$stmt = $db->query("DELETE FROM `$dbname`.`chatmsg` LIMIT 40");//Smaž polovinu zpráv
};
?>
Verze pro tisk
|
Příspívat do diskuze mohou pouze registrovaní uživatelé.
|
|
Vyhledávání software
Vyhledávání článků
28.11.2018 23:56 /František Kučera Prosincový sraz spolku OpenAlt se koná ve středu 5.12.2018 od 16:00 na adrese Zikova 1903/4, Praha 6. Tentokrát navštívíme organizaci CESNET. Na programu jsou dvě přednášky: Distribuované úložiště Ceph (Michal Strnad) a Plně šifrovaný disk na moderním systému (Ondřej Caletka). Následně se přesuneme do některé z nedalekých restaurací, kde budeme pokračovat v diskusi.
Komentářů: 1
12.11.2018 21:28 /Redakce Linuxsoft.cz 22. listopadu 2018 se koná v Praze na Karlově náměstí již pátý ročník konference s tématem Datová centra pro business, která nabídne odpovědi na aktuální a často řešené otázky: Jaké jsou aktuální trendy v oblasti datových center a jak je optimálně využít pro vlastní prospěch? Jak si zajistit odpovídající služby datových center? Podle jakých kritérií vybírat dodavatele služeb? Jak volit vhodné součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně datové centrum spravovat? Jak co nejlépe eliminovat možná rizika? apod. Příznivci LinuxSoftu mohou při registraci uplatnit kód LIN350, který jim přinese zvýhodněné vstupné s 50% slevou.
Přidat komentář
6.11.2018 2:04 /František Kučera Říjnový pražský sraz spolku OpenAlt se koná v listopadu – již tento čtvrtek – 8. 11. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma umění a technologie, IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
4.10.2018 21:30 /Ondřej Čečák LinuxDays 2018 již tento víkend, registrace je otevřená.
Přidat komentář
18.9.2018 23:30 /František Kučera Zářijový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 20. 9. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
9.9.2018 14:15 /Redakce Linuxsoft.cz 20.9.2018 proběhne v pražském Kongresovém centru Vavruška konference Mobilní řešení pro business.
Návštěvníci si vyslechnou mimo jiné přednášky na témata: Nejdůležitější aktuální trendy v oblasti mobilních technologií, správa a zabezpečení mobilních zařízení ve firmách, jak mobilně přistupovat k informačnímu systému firmy, kdy se vyplatí používat odolná mobilní zařízení nebo jak zabezpečit mobilní komunikaci.
Přidat komentář
12.8.2018 16:58 /František Kučera Srpnový pražský sraz spolku OpenAlt se koná ve čtvrtek – 16. 8. 2018 od 19:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát jsou tématem srazu databáze prezentaci svého projektu si pro nás připravil Standa Dzik. Dále bude prostor, abychom probrali nápady na využití IoT a sítě The Things Network, případně další témata.
Přidat komentář
16.7.2018 1:05 /František Kučera Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.
Přidat komentář
Více ...
Přidat zprávičku
Poslední diskuze
31.7.2023 14:13 /
Linda Graham iPhone Services
30.11.2022 9:32 /
Kyle McDermott Hosting download unavailable
13.12.2018 10:57 /
Jan Mareš Re: zavináč
2.12.2018 23:56 /
František Kučera Sraz
5.10.2018 17:12 /
Jakub Kuljovsky Re: Jaký kurz a software by jste doporučili pro začínajcího kodéra?
Více ...
|