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. |
|
| · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | · | | | | |
|