This article shows how to implement a realtime chat system on a web page using some of the most common open source technologies out there. For the web server, Apache will be used. For the back end, MySQL Community Version will be used and PHP as the preprocessor.
It is important that you have sufficient understanding on how PHP, MySQL and AJAX works. Additionally, there are also other issues that should be seriously taken in to consideration. In summary, PHP (data access layer) will be providing the data from the MySQL database (data store). The web page (presentation layer) through AJAX will retrieve this data and present it to the user.
For this example we'll be creating a simple table in a MySQL database. Here's how the code for the database implementation was made.
Database Setup
mysql> create database chat_system;
Query OK, 1 row affected (0.03 sec)
mysql> use chat_system;
Database changed
mysql> create table messages
-> (
-> id int(11) not null auto_increment,
-> msg text,
-> primary key (id)
-> ) engine=innodb;
Query OK, 0 rows affected (0.20 sec)
The chat system will involve only a simple setup. Once inside the main webpage, the user can put something in the text box. After clicking submit, the Javascript function ajaxPost() will validate the text on the textbox. If it's not empty, it's sent to the database chat_system at table messages. If it's successfully sent to the database the file insert.php responsible for the insert command will reply to the main page a success result or else it will document the error and die.
Additionally the webpage will refresh occasionally to show all the elements on the database table messages. In order to do this, the Javascript function ajaxGet() is continually run after each 500ms intervals.
Below is a simple picture describing the dataflow in this system.
Below is the code for the file main.php. This file is the presentation layer. You can actually name this main.html or main.htm because it does not contain any PHP code.
main.php
<!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" xml:lang="en" lang="en">
<head>
<title>Ajax</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function ajaxRequest(){
var activexmodes=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] ;
if (window.ActiveXObject){
for (var i=0; i<activexmodes.length; i++){
try{
return new ActiveXObject(activexmodes[i]);
}
catch(e){
}
}
}
else if (window.XMLHttpRequest)
return new XMLHttpRequest();
else
return false;
}
function ajaxPost(){
// check if the text box has an input as message if not end the function.
var msgvalue=encodeURIComponent(document.getElementById("msg").value);
if (msgvalue.length < 1)
{
return false;
}
var parameters="msg="+msgvalue;
// proceed with the ajax post request;
var mypostrequest = new ajaxRequest();
mypostrequest.onreadystatechange=function(){
if (mypostrequest.readyState==4){
if (mypostrequest.status==200 || window.location.href.indexOf("http")==-1){
document.getElementById("SystemMsgs").innerHTML=mypostrequest.responseText;
}
else{
alert("An error has occured making the request");
}
}
}
mypostrequest.open("POST", "insert.php", true);
mypostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
mypostrequest.send(parameters);
}
function ajaxGet()
{
var mygetrequest = new ajaxRequest();
if (mygetrequest)
{
mygetrequest.onreadystatechange = function(){
if (/4|^complete$/.test(mygetrequest.readyState))
{
document.getElementById('ReloadThis').innerHTML = mygetrequest.responseText;
setTimeout(function() {ajaxGet();}, 500);
}
};
mygetrequest.open('GET', 'fetch.php' + '?' + new Date().getTime(), true);
mygetrequest.send(null);
}
}
</script>
</head>
<body>
<form method="post" name="myForm">
Message: <input type="text" id="msg" name="msg"><br>
<input type="button" value="submit" onClick="ajaxPost()" />
</form>
<br />
<script type="text/javascript">
// will do this every 500ms intervals.
setTimeout(function() {ajaxGet();}, 500);
</script>
<br />
<div id="SystemMsgs"></div>
<div id="ReloadThis"></div>
</body>
</html>
The most important parts are the three Javascript functions called ajaxRequest(), ajaxPost(), and ajaxGet(). The function ajaxRequest() will create the Ajax object. Then ajaxPost() will create a new object from ajaxRequest() and use this to make a post request to the PHP file insert.php which is responsible for the insertion of new data to the database. Since the function ajaxPost() is tied to the onClick event of the main.php's form button, it will activate once the user clicks the submit button. Below is the code for the insert.php file which takes care of the data insertion.
insert.php
<?
// conection settings
$username="bangonkali";
$password="mypass";
$database="chat_system";
$datahost="localhost";
// this is the variable to get from
// the global variable post.
$msg=$_POST['msg'];
// connect and select db
mysql_connect($datahost,$username,$password) or die('Could not connect: ' . mysql_error());
mysql_select_db($database) or die( "Unable to select database");
// define ang get query result
$query = "INSERT INTO messages (msg) VALUES ('$msg')";
$result = mysql_query($query);
// check if result exists then post it. else, error.
if (!$result) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $query;
echo ($message);
}
else{
echo ("Sent successfully!");
}
// close the database.
mysql_close();
?>
The line
document.getElementById("SystemMsgs").innerHTML = mypostrequest.responseText;
on the main.php file will receive the resulting page from insert.php. The resulting page is inserted to the SystemMsgs div section of the main.php file. The result will vary depending on the behavior of the following lines that are found at the insert.php file:
if (!$result) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $query;
echo ($message);
}
else{
echo ("Sent successfully!");
}
After the insertion function ajaxPost() the text located in the div section SystemMsgs will either be "Sent successfully!" or an error message depending on the value of the variable $message.
Below is the code for the fetch.php file which is responsible for updating the innerHTML of the ReloadThis div in the main.php file.
fetch.php
<?php
// conection settings
$username="bangonkali";
$password="mypass";
$database="chat_system";
$datahost="localhost";
// connect and select db
mysql_connect($datahost,$username,$password) or die('Could not connect: ' . mysql_error());
mysql_select_db($database) or die( "Unable to select database");
// define ang get query result
$query = "SELECT msg FROM messages";
$result = mysql_query($query);
// print all results with a new line after each.
while($row = mysql_fetch_array($result))
{
echo $row['msg'];
echo "<br />";
}
mysql_close();
?>
In this case, the function ajaxGet() is rerun after 500ms intervals. The line
document.getElementById('ReloadThis').innerHTML = mygetrequest.responseText;
will replace the innerHTML of the div element ReloadThis in the main.php with the responseText of the GET request made for the file fetch.php.
This scenario is a very simple illustration of how to take advantage of AJAX in developing real time systems, especially chat. This also serves as a future note for myself in case I get in to this kind of project again in the future. Do know that there maybe a lot of best practices that should be used especially in handling data with Ajax. This article does not talk about any best practices. This is just a quick and dirty example for this kind of project.
Additionally, there are a lot of JavaScript libraries out there that can help you in the development of your own Ajax projects. One example would be jQuery!
After creating the MySQL database, you can download the php files attached below. Don't forget to edit the MySQL connection strings on the files fetch.php and insert.php.