[Questo tutorial presuppone una conoscenza di base nel campo della programmazione
in PhP e MySQL]
Chat.php
Per prima cosa, pensiamo all’incastellatura della pagina: è conveniente
creare una pagina di chat così composta: un FRAME grande dove verranno
visualizzate le chattate, e un framino più piccino che fungerà
da campo di imput.
Nell’esempio tutte le pagine hanno estensione .php: questo perché
si suppone che venga usato del codice php anche dove non ce ne sarebbe un bisogno
immediato, se non altro per effettuare controlli sull’esistenza della
sessione (per evitare cioè che utenti maliziosi o casinari possano richiamare
le pagine dalla cronologia senza prima esser passati al login del sito: e dato
che i controlli vanno fatti suando le funzioni php, le pagine devono essere
adatte per il php hypertext processor).
Tornando al discorso della chat, in prima istanza potremmo scrivere così:
<body>
<iframe name="chatView" src="chatview.php" frameborder="0"
framespacing="0" width="100%" height="95%"></iframe>
<iframe name="chatEngine" src="chatEngine.php" frameborder="0"
framespacing="0" width="100%" height="5%" scrolling="no"></iframe>
</body>
Ovviamente questi tag definiscono un body HTML. Alcune precisazioni:
Definita la struttura della pagina (che chiameremo genericamente “chat.php”)
esaminiamo l’architettura di base del frame di imput e del visualizzatore.
Chatengine.php
Cos’ ho chiamato il gestore dell’imput: è esattamente ciò
che suggerisce il nome, un “motore” in grado di inviare una stringa
di testo ad un’altra pagina che poi la processerà. Per fare questo,
si avvale delll’uso dei FORM HTML. La pagina verrà altresì
caricata dentro Chat.php e più precisamente dentro il frame piccolo in
basso, di nome chatEngine: questo lo fa l’attributo src=”Chatengine.php”
che recupera la pagina e la carica nella posizione indicata.
Prima di tutto definiamo il form:
<form name="INform" method="post" action=”Chatdaemon.php”
onSubmit="javascript:location.reload();">
<input type="text" name="message" size="45">
<input type="submit" value="Invia" name="inviato"
onclick="javascript:document.INform.message.focus();">
</form>
Questo form può essere inserito dentro un normale body HTML e può
essere ampliato a piacere, ad esempio (per dirne una) aggiungendo un menu a
tendina di comandi che, se selezionati, scriveranno frasi speciali nel campo
del messaggio che poi potranno essere interpretate dal demone di sistema (Chatdaemon.php)
e usate per avviare comandi quali attacchi, prove di abilità, ecc…nella
sua forma basica, questo gestore processa il testo che riceve senza interpretare
in nessun modo particolare.
L’istruzione javascript nell’intestazione del form serve perchè
ad ogni invio il form va “pulito” dal testo precedente (cosa che
si realizza, tra gli altri metodi, reloadando brutalmente la pagina); quella
dentro l’imput invece serve a far si che il cursore del testo venga “spostato”
ad ogni invio sempre dentro il campo message del form, così da evitare
la necessità di ciccarci sempre dentro per poter scrivere.
Chatdaemon.php
Questo è il cuore della chat: il demone di analisi del testo; qui dentro
possono essere svolte operazioni di semplice formattazione del testo piuttosto
che di vera e propria interpretazione dei comandi per scatenare attacchi o prove
di abilità da parte del personaggio. Tutto tramite l’uso di comandi
speciali, che è il progettista a definire (ad es. posso per convenzione
dire che al testo “!pippo” corrisponde le’secuzione di una
procedura di attacco: in tal caso il demone se ne accorgerà e invece
di visualizzare il testo semplice visualizzerà invece l’output
dell’azione di attacco). Tuttavia in questa versione di base non verranno
definiti interpreti raffianti di comandi: si implementerà un demone becero
che spara a video quello che riceve, ne più ne meno.
Prima di tutto si precisa ke il collegamento a chatdaemon.php da chatview.php
è generato dall’attributo Action specificato nell’intestazione
del form dentro chatengine (action=”Chatdaemon.php”).
In secondo luogo si può passare a definire il demone, dopo aver creato
una intestazione HTML standard:
<html>
<head></head>
<body></body>
</html>
(Avvertenza: tutti i comandi di seguito per la creazione di Chatdaemon.php
vanno inseriti all’interno del tag <body></body>)
Dapprima converrà recuperare l’imput da chatengine e ciò va fatto dentro un blocco PHP, in questa maniera.
<?php
$chat_text=$_POST['message'];
?>
Qui uso l’array globale di variabili di sistema $_POST di php…la spiegazione dell’uso è in qualsiasi libro di programmazione php per l’appunto :P. Cosa faccio? Semplicemente DICHIARO una variabile chiamata chat_text (il simbolico del dollaro davanti è OBBLIGATORIO) e quindi le associo il contenuto della cella chiamata message (creata dentro chatengine automaticamente dal sistema) dell’array $_POST.
Fatto ciò bisogna COLLEGARSI AL DATABASE dove sarà memorizzata una tabella di chat, che salverà (per il tempo di visualizzazione) i messaggi.
<?php
$connection=mysql_connect('localhost',’account’) or die ("Errore
di connessione");
mysql_select_db('database',$connection);
?>
…i parametri ‘account’ e ‘database’ indicano il nome dell’account sulla macchina che ospita e il nome del db ospitato (in cuista la tabella)…variano da macchiana macchina, tipicamente nelle FAQ dei siti di hosting sta scritto come fare ad interfacciarsi con un database ospitato sul server.
La struttura della tabella di chat potrebbe essere la seguente:
CREATE TABLE `chat` (
`ID` varchar(20) default NULL,
`message` longtext,
`locazione` varchar(50) default NULL,
`timein` int(10) default NULL,
KEY `timein` (`timein`)
) TYPE=MyISAM;
Chiunque mastichi un minimo di MySQL dovrebbe raccapezzarsi: come si vede non servono relazioni con decine di campi, molto meglio una struttura pulita e snella. Brevemente il significato dei campi:
La tabella non ha chiave primaria: l’indice da già i vantaggi della primary key ma in più garantisce duplicati e valori nulli. La tabella è di tipo MyISAM. Se la tabella non esiste nel DB ovviamente va cerata, e ciò verrà fatto lanciando questa query dentro MySQL.
Ora dobbiamo creare le info di temporizzazione dei messaggi; serve una data e ora da visualizzare accanto al messaggio in chat (per fare i fighi…) e il già citato timestamp che invece temporizzerà il refresh:
<?php
$time=mysql_fetch_row(mysql_query("SELECT curtime()",$connection));
$tmptime=time();
?>
La funzione curtime() e nativa di MySQL (infatti si usa dentro una query SELECT) e seleziona l’ora corrente del server: la funzione time() invece è di PhP genera un timestamp che poi verrà salvato dentro il campo timein della tabella chat. Da notare che vanno dichiarate come valore di una variabile (rispettivamente $time e $tmptime) per salvare il valore e poi usarlo.
Ora vanno memorizzate le info nella tabella; si suppone che nella variabile $chatter sia memorizzato il nome dell’utente che scrive in chat, e che dentro $locazione ci sia la locazione corrente: come già detto tali dati vanno salvati in qualche modo, e le modalità per la loro gestione dipendono dalle scelte del progettista del database. torniamo al problema:
<?php
$chat_text=addslashes($chat_text);
$chat_text[0]=strtolower($chat_text[0]);
$chat_text="<p align=justify>" . $time[0]. " - " .
"<b><font face=arial size=2>$chatter</b>" . ":
" . htmlspecialchars($chat_text) . "</font></p>";
$log_chat=mysql_query("INSERT INTO chat(ID,message,locazione,timein) VALUES
('$chatter','$chat_text','$locazione','$tmptime')",$connection);
?>
Questo codice FORMATTA la variabile $chat_text (che contiene i dati del form, cioè l’imput utente): nella fattispecie aggiunge delle barre retroverse, che nella sintassi PHP sono necessarie se si vuole inserire in un database un carattere che sarebbe un carattere speciale delle espressioni MySQL (lo fa la funzione addslashes($stringa_imput)), e poi rende minuscola la lettera iniziale del messaggio - lo fa la funzione strtolower($stringa_imput); quindi costruisce una stringa concatenando (operatore punto) dei tag HTML per generare un testo color blu il nome del personaggio, l’ora corrente (contenuta in $time[0]) e il testo precedentemente formattato: da notare le virgolette “” che racchiudono SOLO i tag HTML e si interrompono prima dell’operatore punto, e l’uso che si fa delle variabili: in pratica si ricicla la variabile $chat_text che prima conteneva solo il messaggio, sostituendola invece col messaggio concatenato ai tag e formattato bene.
Fatto questo si possono inserire i dati nel database: questo viene fatto dalla funzione MYSQL_QUERY(“testo query”,$var_connessione) che prende in imput una query mysql (racchiusa tra “”) e una variabile contenente info di connessione al database (la $connection definita sopra all’inizio di tutto). Notare l’ordine di inserimento dei valori, che riprende quello della successione dei campi nella tabella, e gli apici singoli ‘’ nella sezione VALUES().
Nota conclusiva e IMPORTANTE: questo demone è una pagina invisibile all’utente, su cui il chatter non ha controllo diretto: essa lavora in background, nascosta, processa l’imput dietro le quinte con maggiore o minore rapidità (dipende dal server): per far si che il controllo venga rimandato al visualizzatore al termine della pagina dovremo inviare un HEADER http, vale a dire un insieme di info al server per dirgli di visualizzare una nuova pagina. Anche qui php ci viene in aiuto, sarà infatti sufficiente scrivere:
<?php
header("Location:chatview.php",true);
?>
per redirettare il controllo dalla pagina nascosta alla pagina visibile all’utente.
Questi elementi componenti il demone di sistema possono venire inseriti senza problemi in un blocco <body></body>, soltanto ricordarsi le parentesi speciali <?php ?> per dire che tutto ciò che è compreso è codice php e va trattato come tale.
Chatview.php
Chatview.php è il visualizzatore delle pagine di chat: si tratta della pagina visibile dove viene visualizzato il prodotto del lavoro (invisibile) di Chatdaemon.php: il controllo viene passato grazie alla funzione header().
Le operazioni che devono essere compiute dentro Chatview sono le seguenti:
Occupiamoci del primo punto: definita una intestazione HTML standard:
<html>
<head></head>
<body></body>
</html>
Aggiungeremo nella <head> del documento un tag di meta-http per effettuare il refresh della pagina:
<meta http-equiv="refresh" content="10,chatview.php">
Ciò dice al server di ricaricare la pagina ogni 10 secondi: va da se che nel caso peggiore se un utente invia a refresh appena avvenuto un altro utente loggiato al sito vedrà la frase inviata dopo che i 10 secondi sono passati.
Quindi all’interno del solito <body></body> inseriremo le stringhe di connessione (senza dimenticare le parentesi angolate <?php e ?>):
<?php
$connection=mysql_connect('localhost',’account’) or die ("Errore di connessione");
mysql_select_db('database',$connection);
?>
E successivamente recupereremo le informazioni utili a stabilire se un messaggio è “scaduto”, cioè se deve essere cancellato perché il tempo di refresh è passato interamente: tale tempo di refresh è qui segnato in 10 minuti.
<?php
$actualtime=time();
$refresh=mysql_query("DELETE FROM chat WHERE timein+600<'$actualtime'",$connection);
?>
La query DELETE FROM … WHERE ... cancella semplicemente dei record dalla tabella chat; notare la struttura per dire “se sono passati 10 minuti il messaggio è obsoleto”: la time() lavora con i secondi, quindi dovrò esprimere il tempo di refresh in secondi (600 per 10 minuti, appunto); cancellerò i records dove il campo timein aumentato di 600 secondi è INFERIORE al timestamp attuale di sistema (recuperato con la time()).
Fatto questo, la parte interessante: dovrò recuperare TUTTI i messaggi dalla tabella e visualizzarli, e per fare questo mi avvarrò dell’uso di un ciclo FOR.
<?php
$exec_reading=mysql_query("SELECT * FROM chat WHERE locazione='$locazione_attuale' ORDER BY timein DESC",$connection)
$numrows=mysql_num_rows($exec_reading);
if($numrows!=0)
{
for($x=0;$x<$numrows;$x++)
{
$resrow=mysql_fetch_row($exec_reading); /*recupero tutti i messaggi non cancellati
della tabella*/
$nomeChat=$resrow[0];
$messChat=stripslashes($resrow[1]);
echo $messChat;
}
}
?>
La prima istruzione salva semplicemente una query di recupero in una variabile
($exec_reading): la query recupera OGNI campo di ogni record (SELECT *) dalla
tabella chat, riordinandoli in ordine decrescente per inserimento così
da far comparire in alto sullo schermo i messaggi inseriti per ultimi (ORDER
BY timein DESC); successivamente, a questa query viene applicata la funzione
mysql_num_rows(), che conta il NUMERO di records recuperati da una query salvando
tale numero dentro la variabile $numrows.
Quindi, SE recupero ALMENO un record (if($numrows!=0)) posso dare il via all’iterazione
del ciclo, che PER OGNI record recuperato salverà i valori dei campi
in un array chiamato $resrow[], con l’uso della funzione mysql_fetch_row()
applicata sulla variabile ke memorizzata la query.
Quindi l’operatore echo di PhP stamperà a video il messaggio formattato
contenuto in messChat (si trova nella posizione zero dell’array $resrow[],
ma lo salvo dentro questa nuova variabile, $messchat, per maggior chiarezza).
Questa procedura è più macchinosa: non posso compattare più query ma devo epr forza prima recuperare il numero di records e successivamente iterare esaminando ogni record uno per volta.
Seguendo queste linee-guida e con le dovute consultazioni a qualsiasi manuale di PhP e HTML sarete in grado, se tutto va bene, di realizzare una versione base di chat, discretamente efficiente perché basata su una tabella snella e indicizzata. Ovviamente non si tratta del BlackEngine che ho progettato, ma della prima base da cui partire se proprio siete a digiuno e nessuno vi ha mai spiegato come fare una chat.
Per eventuali dubbi: blackangel_warlord@yahoo.it
Risponderò compatibilmente col tempo che ho e con gli impegni di studio/lavoro :-P