Home arrow XML arrow Page 4 - Building an AJAX-Based Chat: Interacting With a Database
XML

Building an AJAX-Based Chat: Interacting With a Database


In this third and final part of a tutorial that explains how to build an AJAX-based chat application, Alejandro Gervasio covers creating the PHP files that directly interact with a MySQL database, adding and fetching chat messages. He also makes some suggestions for expanding the functions of the application.

Author Info:
By: Alejandro Gervasio
Rating: 4 stars4 stars4 stars4 stars4 stars / 52
November 21, 2005
TABLE OF CONTENTS:
  1. · Building an AJAX-Based Chat: Interacting With a Database
  2. · Adding messages to the database: looking at the “sendchatdata.php” file
  3. · Reading messages from the server: defining the “getchatdata.php” file
  4. · Putting the files together: the complete chat application at a glance

print this article
SEARCH DEVARTICLES

Building an AJAX-Based Chat: Interacting With a Database - Putting the files together: the complete chat application at a glance
(Page 4 of 4 )

As I said before, here is the complete list of files that composes the AJAX-driven chat. The list begins with the “chatlogin.php” file:

<?php
// register nickname as session variable
// & redirect to chat page
if($_POST['enter']){
    session_start();
    $_SESSION['user']=$_POST['nickname'];
    header('location:ajaxchat.php');
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>CHAT LOGIN</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body {
    background: #eee;
    margin: 0px;
    padding: 0px;
}
h1 {
    font: bold 36px Arial, Helvetica, sans-
serif;
    text-align: center;
}
div {
    width: 50%;
    background: #99f;
    border: 1px solid #000;
    padding: 20px;
    margin-left: auto;
    margin-right: auto;
}
p {
    font: normal 12px Verdana, Arial, Helvetica, sans-serif;
    color: #000;
}
</style>
<script language="javascript">
window.onload=function(){
    var nick=document.getElementsByTagName
('form')[0].elements['nickname'];
    if(!nick){return};
    nick.focus();
}
</script>
</head>
<body>
<h1>AJAX-BASED CHAT SYSTEM</h1>
<div>
<form action="<?php echo $_SERVER['PHP_SELF']?
>" method="post">
<p>Enter your nickname <input type="text"
name="nickname" />
<input type="submit" name="enter" value="Go!" /></p>
</form>
</div>
</body>
</html>

Now, the lists continues with the definition for the “ajaxchat.php” file:

<?php
// get user name
session_start();
$user=$_SESSION['user'];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-
transitional.dtd
">
<html>
<head>
<title>AJAX-BASED CHAT SYSTEM</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body {
    margin: 0;
    padding: 0;
}
p {
    font: normal 14px Arial, Helvetica, sans-
serif;
    color: #000;
    margin-bottom: -12px;
}
span {
    margin-left: 20px;
    font: bold 12px Verdana, Arial, Helvetica,
sans-serif;
    color: #003399;
}
form {
    display: inline;
}
.msgfield {
    font: normal 14px Arial, Helvetica, sans-
serif;
    color: #000;
    width: 400px;
}
div#messages {
    height: 450px;
    background: #d9dcea;
    padding: 10px 0px 10px 2px;
    border: 1px solid #000;
}
div#messagebox {
    background: #ccf;
    border-left: 1px solid #000;
    border-right: 1px solid #000;
    border-bottom: 1px solid #000;
    padding: 10px;
}
</style>
<script language="javascript">
/*
*******************************************
AJAX-Based Chat System
Author: Alejandro Gervasio
Version: 1.0
*******************************************
*/
// getXMLHttpRequest object
function getXMLHttpRequestObject(){
    var xmlobj;
    // check for existing requests
    if(xmlobj!=null&&xmlobj.readyState!
=0&&xmlobj.readyState!=4){
        xmlobj.abort();
    }
    try{
        // instantiate object for Mozilla,
Nestcape, etc.
        xmlobj=new XMLHttpRequest();
    }
    catch(e){
        try{
            // instantiate object for Internet
Explorer
            xmlobj=new ActiveXObject
('Microsoft.XMLHTTP');
        }
        catch(e){
            // Ajax is not supported by the
browser
            xmlobj=null;
            return false;
        }
    }
    return xmlobj;
}
// check status of sender object
function senderStatusChecker(){
    // check if request is completed
    if(senderXMLHttpObj.readyState==4){
        if(senderXMLHttpObj.status==200){
 // if status == 200 display chat data
 displayChatData(senderXMLHttpObj);   
        }
        else{
            alert('Failed to get response :'+
senderXMLHttpObj.statusText);
        }
    }
}
// check status of receiver object
function receiverStatusChecker(){
    // if request is completed
    if(receiverXMLHttpObj.readyState==4){
        if(receiverXMLHttpObj.status==200){
 // if status == 200 display chat data
 displayChatData(receiverXMLHttpObj);
        }
        else{
            alert('Failed to get response :'+
receiverXMLHttpObj.statusText);
        }
    }
}
// get messages from database each 5 seconds
function getChatData(){
    receiverXMLHttpObj.open('GET','getchatdata.php',true);
    receiverXMLHttpObj.send(null);
    receiverXMLHttpObj.onreadystatechange=
receiverStatusChecker;
    setTimeout('getChatData()',5*1000);
}
// display messages
function displayChatData(reqObj){
    // remove previous messages
    var mdiv=document.getElementById
('messages');
    if(!mdiv){return};
    mdiv.innerHTML='';
    var messages=reqObj.responseText.split
('|');
    // display messages
    for(var i=0;i<messages.length;i++){
        var p=document.createElement('p');
        p.appendChild(document.createTextNode
(messages[(messages.length-1)-i]));
        mdiv.appendChild(p);
    }
}
// send user message
function sendMessage(){
    var user='<?php echo $user?>';
    var message=document.getElementsByTagName
('form')[0].elements[0].value;
    if(message.length>100){message=message.substring(0,100)};
    // open socket connection
    senderXMLHttpObj.open('POST','sendchatdata.php',true);
    // set form http header
    senderXMLHttpObj.setRequestHeader('Content-
Type','application/x-www-form-urlencoded');
    senderXMLHttpObj.send('user='+user+'&message='+message);
    senderXMLHttpObj.onreadystatechange=
senderStatusChecker;
}
// create messages board
function createMessageBoard(){
    var mdiv=document.createElement('div');
    mdiv.setAttribute('id','messages');
    document.getElementsByTagName('body')[0].appendChild(mdiv);
}
// create message input box
function createMessageBox(){
    // create message box container
    var mdiv=document.createElement('div');
    mdiv.setAttribute('id','messagebox');
    // create message form
    var mform=document.createElement('form');
    // create message box
    var mbox=document.createElement('input');
    mbox.setAttribute('type','text');
    mbox.setAttribute('name','message');
    mbox.className='msgfield';
    // create 'send' button
    var mbutton=document.createElement
('input');
    mbutton.setAttribute('type','button');
    mbutton.setAttribute('value','Send');
    mbutton.onclick=sendMessage;
    // create login text
    var sp=document.createElement('span');
    sp.appendChild(document.createTextNode
('Logged in as: <?php echo $user?>'));
    // append elements
    mform.appendChild(mbox);
    mform.appendChild(mbutton);
    mform.appendChild(sp);
    mdiv.appendChild(mform);
    document.getElementsByTagName('body')
[0].appendChild(mdiv);
    mbox.focus();
    mbox.onfocus=function(){this.value='';}
}
// initialize chat
function intitializeChat(){
    if(document.getElementById&&document.
getElementsByTagName&&document.createElement){
        createMessageBoard();
        createMessageBox();
        getChatData();
    }
}
// instantiate sender XMLHttpRequest object
var senderXMLHttpObj=getXMLHttpRequestObject();
// instantiate receiver XMLHttpRequest object
var receiverXMLHttpObj=getXMLHttpRequestObject
();
// initialize chat
window.onload=intitializeChat;
</script>
</head>
<body>
</body>
</html>

Next, there’s the definition for the “sendchatdata.php” and “getchatdata.php” files:

// include class file
require_once 'mysql_class.php';
// connect to MySQL
$db=&new MySQL(array('host'=>'host','user'=>'user','password'=>
'password','database'=>'chat'));
// get user & message
$user=$_POST['user'];
$message=$_POST['message'];
// insert new message into database table
$db->query("INSERT INTO messages SET user='$user',message='$message'");
// get ID from last inserted message
$id=$db->getInsertID();
// delete messages when ID > 1000
if($id>1000){
    $db->query("DELETE FROM messages WHERE id <
($id-10)");
}
// retrieve last 20 messages
$db->query("SELECT user,message FROM messages
WHERE id <=$id ORDER BY id DESC LIMIT 20");
// send messages to the client
while($row=$db->fetchRow()){
 echo '<'.$row['user'].'>'.$row['message'].'|';
}

// include class file
require_once 'mysql_class.php';
// connect to MySQL
$db=&new MySQL(array('host'=>'host','user'=>'user','password'=>
'password','database'=>'chat'));
// retrieve last 20 messages
$db->query("SELECT user,message FROM messages
ORDER BY id DESC LIMIT 20");
// send messages to the client
while($row=$db->fetchRow()){
    echo '<'.$row['user'].'>'.$row
['message'].'|';
}

Finally, here is the listing for the “MySQL” class and the “chat.sql” file:

<?php

class MySQL{
    var $conId; // connection identifier
    var $host; // MySQL host
    var $user; // MySQL username
    var $password; // MySQL password
    var $database; // MySQL database
    var $result; // MySQL result set
    // constructor
    function MySQL($options=array()){
        // validate incoming parameters
        if(count($options)<1){
            trigger_error('No connection
parameters were provided');
            exit();
        }
        foreach($options as $parameter=>$value){
            if(!$parameter||!$value){
                trigger_error('Invalid
connection parameter');
                exit();
            }
            $this->{$parameter}=$value;
        }
        // connect to MySQL
        $this->connectDB();
    }
    // connect to MYSQL server and select
database
    function connectDB(){
        if(!$this->conId=mysql_connect($this-
>host,$this->user,$this->password)){
            trigger_error('Error connecting to
the server '.mysql_error());
            exit();
        }
        if(!mysql_select_db($this-
>database,$this->conId)){
 trigger_error('Error selecting database
'.mysql_error());
 exit();
        }
    }
    // perform query
    function query($query){
        if(!$this->result=mysql_query
($query,$this->conId)){
 trigger_error('Error performing query
'.$query.' '.mysql_error());
 exit();
        }
    }
    // fetch row
    function fetchRow(){
        return mysql_fetch_array($this-
>result,MYSQL_ASSOC);
    }
    // count rows
    function countRows(){
        if(!$rows=mysql_num_rows($this-
>result)){
 trigger_error('Error counting rows');
 exit();
        }
        return $rows;
    }
    // count affected rows
    function countAffectedRows(){
        if(!$rows=mysql_affected_rows($this-
>conId)){
 trigger_error('Error counting affected rows');
 exit();
        }
        return $rows;
    }
    // get ID from last inserted row
    function getInsertID(){
        if(!$id=mysql_insert_id($this->conId)){
 trigger_error('Error getting ID');
 exit();
        }
        return $id;
    }
    // seek row
    function seekRow($row=0){
        if(!mysql_data_seek($this-
>result,$row)){
 trigger_error('Error seeking data');
 exit();
        }
    }
}
?>

CREATE TABLE messages (
    id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT
PRIMARY KEY,
    user CHAR(256) NOT NULL,
    message CHAR(256) NOT NULL
)

All right, I think that’s all. Don’t tell me that I didn’t warn you! Anyway, if you’re not feeling very comfortable with copying and pasting the complete code of the chat, you can download all the application files here

Summary and further improvements

Finally, this series has finished. Over this three-part tutorial, you’ve hopefully learned in a friendly way how to build a chat application by utilizing the popular AJAX technology, in conjunction with some simple PHP scripts. From the barebones structure, to the specific definition for JavaScript requester modules and PHP files, the coding experience has been didactical. Of course, you may have realized that the application can be enhanced in many ways. One possible improvement would be giving users the ability to send private messages, like popular messaging programs, or including icons within the comments.

Even when private messages can be hard work, “smilies” can be easily introduced by using regular expressions. However, that will be left to you as homework. Now that you know how to build an AJAX-based chat, you can leap forward and develop a full-fledged chatting application. See you in the next tutorial!


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus
XML ARTICLES

- Open XML Finally Supported by MS Office
- XML Features Added to Two Systems
- Using Regions with XSL Formatting Objects
- Using XSL Formatting Objects
- More Schematron Features
- Schematron Patterns and Validation
- Using Schematron
- Datatypes and More in RELAX NG
- Providing Options in RELAX NG
- An Introduction to RELAX NG
- Path, Predicates, and XQuery
- Using Predicates with XQuery
- Navigating Input Documents Using Paths
- XML Basics
- Introduction to XPath

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials