XMLHttp tutorial (who's online example)

Tutorials on PHP, databases and other aspects of web development. Before posting a question, check in here to see whether there's a tutorial that covers your problem.

Moderator: General Moderators

Locked
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

XMLHttp tutorial (who's online example)

Post by Burrito »

Thanks to smpdawg for turning me on to XMLHttp...since my introduction I've gone hog-wild with it and if you've read a lot of my posts, you're bound to have seen me bring it up several times.

What is XMLHttp?

Courtesy of 4guysfromrolla:
It is an object that was originally designed by Microsoft to provide client-side access to XML documents on remote servers through the HTTP protocol. It exposes a simple API which allows you to send requests (yes, even POSTS) and get the resultant XML, HTML or binary data!

It has since grown and is now available on most popular browsers using Javascript as a vehicle.

What can XMLHttp do for me?
A question that comes up on this forum consistently is, "how can I retrieve server side information without refreshing/reloading a page["
There are few answers and one that is little known about is XMLHttp. XMLHttp allows a browser to request a page from a server and return information to the loaded page without the necessity of refreshing/reloading the page. The information can then be placed into a javascript variable and handled on the currently loaded page.

Is XMLHttp slow?
when compared to the alternatives (flash, java applets etc), XMLHttp is probably a bit slower as there is not a persistent connection to the server from the client. The speed at which data is returned from the server also depends entirely on your connection to the web server. In other words, if you request a page normally and it takes 15 seconds for the server to respond (not load the page mind you...respond), the same would hold true for the XMLHttp object to return a response. I have used XMLHttp for chat applications, verifying form data (prior to form submission), updating database tables, etc and have been very pleased with the experience.

Is XMLHttp Ajax?
XMLHttp is the precursor to ajax and ajax actually uses XMLHttp to work. Understanding XMLHttp will significantly help you understand and consequently develop applications that are Ajax driven. For more information on Ajax alone, try googling it and you'll come up with a plethora of information.


Ok now to the goods:

We're going to use XMLHttp to generate a page for the imfamous "who's online" feature on a lot of web sites. Unlike most however, this will be a "realtime" check of people who are on your website at any given moment (within 30 seconds for the example).

The first step in using XMLHttp is to create the object so the browser has a method for establishing a connection to the server. I typically do this in a try/catch so that if it dies, I can still run other JS on my page:

Code: Select all

try{
	if (window.XMLHttpRequest){ // check for firefox and other browsers

		reqsend = new XMLHttpRequest(); // create object for ff and other browsers
	}else{ // not firefox or the like...
		reqsend = new ActiveXObject(&quote;Microsoft.XMLHTTP&quote;); // create object for IE 5.0 or later (at least I think it's 5.0 ^o)
	}
}catch(e){
 
};
Ok, now we have our object created so we can do something with it. As mentioned at the top of this tutorial, XMLHttp can be used to gather data using POST or GET. For this example we will use POST (although either would work here, but POST took me longer to figure out so I'll save you the time ;))

We're going to create a function that will be called on regular intervals to:
1) update the database to let it know that we're still online
2) fetch a list of users who are currently online

again, I put this in a try/catch block just in case, in the real world, you'd want to supply an alternative in case it fails...

Code: Select all

function updateIt(){
	try{
		reqsend.open("POST", "online.php", true); // here we set the request type, the page we're requesting and whether or not we want it to be asyncronous (true is asyncronous and is the default)
		var stuff = "upd=1&who=<?=$_SESSION['loggedinid'];?>";  // here we set a string with the post vars...more on this later
		reqsend.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); // because we're using POST, we need to set some headers...this is what took me a long time to figure out
		reqsend.setRequestHeader("Content-Length",stuff.length); // we need to set the length of the amount of information we're sending and this is dynamic as it's based on the length of the stuff string var
		reqsend.send(stuff); // next we actually send the information and perform our "request"
		
		reqsend.onreadystatechange = function(){  // create a function that is called on a change (response received) from the server
			if (reqsend.readyState == 4 && reqsend.status == 200) {
			/* here we're looking to make sure the page has been fully loaded (complete) and that we did not receive an error from the server.  The readyState options are as follows:
			Object status integer:
			0 = uninitialized
			1 = loading
			2 = loaded
			3 = interactive
			4 = complete
			
			the status is just looking for the page status of the server ie: 404=page not found 500=internal server error 200=all is good, eat gravy etc...
			*/
				document.getElementById('namez').innerHTML = reqsend.responseText; // finally we need to update the page with the list of online users using innerHTML
			}
		};
	}catch(e){
		location = "online.php";
	}
	setTimeout("updateIt()",10000); // recall the function every 10 seconds
}

That's all there is to it! Of course we need some php on the back end to query the database and send us responses and we need an html page to list all of those users:

This requires a table (called online here) with the following fields:
username -> varchar(255)
userid -> int
last -> datetime

this also assumes you have a couple session vars set, one with the username "loggedin" and one with the user id "loggedinid"

Code: Select all

<?
require_once("includes/dbConnect.inc.php"); // database connectivity stuff mysql_connect() etc
require_once("includes/session.inc.php"); // session stuff session_start() etc
if(!isset($_POST['upd'])){ // check to see if this is the first page load, or if it's coming from XMLHttp
    mysql_query("update online set last = now() where userid = ".$_SESSION['loggedinid'])
        or die("update death ".mysql_error()); // update the table for "returning users"
    $tryupdate = mysql_affected_rows(); // check to see if it was a returning user
    if(!$tryupdate != 0){
        mysql_query("insert into online 
        (
        username,
        userid,
        last
        )
        values
        (
        '".mysql_escape_string($_SESSION['loggedin'])."',
        ".$_SESSION['loggedinid'].",
        now()
        )")
            or die("insert death ".mysql_error()); // insert a new row for non-returning users
    } // end if for need to insert new row
} // end if for post upd set
$getnames = mysql_query("select * from online where last > '".date("Y-m-d H:i:s", time() - 30)."' order by username")
    or die(mysql_error()); // get list of users who are online (within 30 seconds)
if(isset($_POST['upd'])){ //stuff below came from XMLHttp so work accordingly
    mysql_query("update online set last = now() where userid = ".$_POST['who'])
        or die(mysql_error());  //only need update here as they will have a record for sure based on the fact it was created when they entered the page
    $nameslist = "";
    while($gtnames = mysql_fetch_assoc($getnames)){
        $nameslist .= addslashes($gtnames['username'])."<br>"; // generate list of names of people online
    } // end while for result set 
    echo $nameslist;
    exit;
} // end if for need to show update
?>
now the html

Code: Select all

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
<html>
<head>
	<title>Online</title>
<link rel="stylesheet" href="styles/style.css">
 
</head>
 
<body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" onLoad="updateIt()">
 
<div align="center">
<span id="namez"></span>
</div>
 
 
</body>
</html>
Whola!!! A fully functional realtime "who's online" page that you can include with an iframe or whatever method you choose.

here's the full code:

Code: Select all

<?
require_once("includes/dbConnect.inc.php");
require_once("includes/session.inc.php");
if(!isset($_POST['upd'])){
    mysql_query("update online set last = now() where userid = ".$_SESSION['loggedinid'])
        or die("update death ".mysql_error());
    $tryupdate = mysql_affected_rows();
    if(!$tryupdate != 0){
        mysql_query("insert into online 
        (
        username,
        userid,
        last
        )
        values
        (
        '".mysql_escape_string($_SESSION['loggedin'])."',
        ".$_SESSION['loggedinid'].",
        now()
        )")
            or die("insert death ".mysql_error());
    } // end if for need to insert new row...burrito
} // end if for post upd set...burrito
$getnames = mysql_query("select * from online where last > '".date("Y-m-d H:i:s", time() - 30)."' order by username")
    or die(mysql_error());
if(isset($_POST['upd'])){
    mysql_query("update online set last = now() where userid = ".$_POST['who'])
        or die(mysql_error());
    $nameslist = "";
    while($gtnames = mysql_fetch_assoc($getnames)){
        $nameslist .= addslashes($gtnames['username'])."<br>"; 
    } // end while for result set...burrito 
    echo $nameslist;
    exit;
} // end if for need to show update...burrito
?>

 
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
<html>
<head>
    <title>Online</title>
<link rel="stylesheet" href="styles/style.css">
<script>
try{
    if (window.XMLHttpRequest){
        reqsend = new XMLHttpRequest();
    }else{
        reqsend = new ActiveXObject("Microsoft.XMLHTTP");
    }
}catch(e){
 
};
function updateIt(){
    try{
        reqsend.open("POST", "online.php", true);
        var stuff = "upd=1&who=<?=$_SESSION['loggedinid'];?>";
 
        reqsend.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        reqsend.setRequestHeader("Content-Length",stuff.length);
        reqsend.send(stuff);
        
        reqsend.onreadystatechange = function(){
            if (reqsend.readyState == 4 && reqsend.status == 200) {
                document.getElementById('namez').innerHTML = reqsend.responseText;
            }
        };
    }catch(e){
        location = "online.php";
    }
    setTimeout("updateIt()",10000);
}
</script>
</head>
 
<body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" onLoad="updateIt()">
 
<div align="center">
<span id="namez"></span>
</div>
 
 
</body>
</html>

happy XMLHttp'ing
User avatar
JayBird
Admin
Posts: 4524
Joined: Wed Aug 13, 2003 7:02 am
Location: York, UK
Contact:

Post by JayBird »

looking good buddy, cant wait to give it a go when i need the function in an application.

I can see it opening up new possibilities

Thanks
User avatar
sakhsen
Forum Newbie
Posts: 6
Joined: Thu Mar 10, 2011 1:56 am
Location: Madurai India
Contact:

Re: XMLHttp tutorial (who's online example)

Post by sakhsen »

Informative and good to learn xmlhttp. Would help better if you ive us a complete example
Locked