[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: i nomi dei frames sono NECESSARI (vediamo dopo il perché) gli attributi che ho specificato servono per dare un aspetto gradevole ai frames, eliminando tabulazioni e spazi molesti, bordi ecc l’altezza è fissata in percentuale della pagina, per garantire una certa uniformità di visualizzazione anche su monitor di grandezza diversa; la larghezza l’ho messa al 100% della pagina. l’attributo “scrolling=no” serve per evitare che il framino di imput possa venire scrollato dall’utente (cioè mosso tramite rotellina del mouse in alto e in basso) 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: ID è il nome del personaggio che invia la riga di testo: va recuperato in qualche modo, ad esempio da una variabile di sessione (rimando a manuali di programmazione php!), le modalità sono lasciate alla discrezione del progettista del sito. message è il messaggio vero e proprio locazione è la locazione corrente del PG: anche questa va recuperata, ad esempio da una var di sessione settata al login del personaggio sul sito. timein è un timestamp, vale a dire una sequenza di 10 cifre apparentemente senza senso…poco importa che siano i secondi passati dal 1/1/1970 ad oggi…ce ne serviamo per TEMPORIZZARE i messaggi. Inoltre su questo attributo è definito un INDICE generico, che serve per incrementare le prestazioni ella tabella per quanto riguarda la ricerca e la visualizzazione di messaggi. 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: refresh della chat ogni tot. secondi visualizzazione dei messaggi 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