Web 2.0

Simple AJAX chat in PHP

Tagged:  

Over at the .NET Butchering (and JAVA messes) blog they have posted a very good tutorial on creating a Chat application in PHP using Ajax. In Web 2.0 social applications chat is very often a desired feature.

Below is an excerpt from the tutorial.

The first thing to be done is creating MySQL tables:



CREATE TABLE `db_name`.`chat_rooms` (

`id` int(10) unsigned NOT NULL auto_increment,

`name` varchar(45) NOT NULL,

`description` text NOT NULL,

`table_name` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;



CREATE TABLE `db_name`.`roomX` (

`id` int(10) unsigned NOT NULL auto_increment,

`date` datetime NOT NULL,

`message` text NOT NULL,

`user` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

The first table, chat_rooms, contains a list of all available chat rooms, used to know wich table name will be used for each room. The second one, roomX is a template for a "chat room-like" table: it contains the date (date+time) of each message, the message itself and the user that inputed it (actually it should be an integer, that refers to an appropriate users table, but this is simple version of the script without logging features).

The first thing we're gonna do is execute those SQL scripts (we will be using MySQL and PHP native methods) replacing "roomX" with i.e. "friends_table", and after that we're going to populate the first table, to add an available chat room:



INSERT INTO chat_rooms(name,description,table_name)

VALUES("Friends chat","Comment...","friends_table");

The next step is to compose the "web application". Let's see this picture:

We will use a main page, chat.php, a dinamically reloaded page, room.php and a simple iframe with inside the page sender.php with some controls to post a message.

Let's see chat.php, removing all HTML stuff (like header and formatting, that's up to you):



<?php

session_start();

/* probabily login stuff */

$_SESSION['chat_time'] = $date;

?>

<script type="text/javascript" src="timer.js"></script>

<script type="text/javascript" src="httpRequest.js"></script>

<script language="javascript">

var chatRoomId=<?=$charRoomChoosen?>;

</script>

<body onload="InitializeTimer(); StartTheTimer();">

<div id="chatText" style="overflow:auto;"></div>

<iframe src="sender.php" name="msgFrame"></iframe>

</body>

We'll talk further about the session variable chat_time; I've added 2 javascript scripts: the first one is a simple timer, the second one contains some methods to make HTTP requests.
This is httpRequest.js:



var xmlHttp;



function loadURL()

{

xmlHttp=GetXmlHttpObject()

if (xmlHttp==null)

{

alert ("Browser does not support HTTP Request")

return

}

var url="room.php?chatRoomId="+charRoomId;

xmlHttp.onreadystatechange=stateChanged;

xmlHttp.open("GET",url,true);

xmlHttp.send(null)

}



function stateChanged()

{

if (xmlHttp.readyState==4 xmlHttp.readyState=="complete")

{

/* trim message */

var newlines = xmlHttp.responseText.replace(/^\s+\s+$/g,"");

if(newlines!='')

{

var html = document.getElementById("chatText").innerHTML;

document.getElementById("chatText").innerHTML = html + newlines;

document.getElementById("chatText").scrollTop=20000000;

}



}

}



function GetXmlHttpObject()

{

var xmlHttp=null;

try

{

// Firefox, Opera 8.0+, Safari

xmlHttp=new XMLHttpRequest();

}

catch (e)

{

//Internet Explorer

try

{xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");}

catch (e){xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}

}

return xmlHttp;

}

This class does an HTTP request (using Firefox, Explorer and other browser Request objects), as I explained in the [Javascript]XML Loading post, and writes the result inside the DIV with id chatText, calling the room.php script (that actually outputs last message sent to the room). The charRoomId used as a parameter of the calling method, is a global variable defined in the chat.php header using a PHP variabile (it should be a $_REQUEST variable).

As we are using asyncronous calls, we need a component that recalls this request periodically. This is the code below (timer.js):



var secs;

var timerID = null;

var timerRunning = false;

var delay = 500;



function InitializeTimer()

{

// Set the length of the timer, in seconds

secs = 1;

StopTheClock();

StartTheTimer();

}



function StopTheClock()

{

if(timerRunning)

clearTimeout(timerID);

timerRunning = false;

}



function StartTheTimer()

{

if (secs==0)

{

StopTheClock();

// Here's where you put something useful that's

// supposed to happen after the allotted time.

// For example, you could display a message:

loadURL();

secs = 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

else

{

self.status = secs;

secs = secs - 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

}

This is a timer, called from the chat.php page with onLoad method, that recalls each delay milliseconds the function loadURL() function, defined inside the previous js file.

Now let's see what is inside the chat.php file:



<?php



/* **************** SESSION VARIABLES **************************** */

session_start();



if(!isset($_SESSION['chat_time']))

{

$_SESSION['chat_time'] = date("Y-m-d H:i:s");

$_SESSION['chat_time_delete'] = time();

}





/************** DB connection ********************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********** RETRIEVES THE NAME OF THE CHAT ROOM TABLE NAME **********/

function getChatTableName($connection,$chatRoomId)

{

/* recupera il nome della tabella della chat room */

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}



/******************* MESSAGE VISUALIZATION ********************************/





$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selection char room.";

exit();

}

$login_date = $_SESSION['chat_time'];



/* load messages */

$query = "SELECT c.message, c.date, c.user FROM ".$tableName." c WHERE c.date > '".$login_date

."' ORDER BY c.date ASC ";

$result = mysql_query($query,$connection);



$last = "";

while($row=mysql_fetch_array($result))

{

$message = html_entity_decode($row['message']);

echo "[".$row['user']."][".$row['date']."] ".$message." <br/>";

$_SESSION['chat_time'] = $row['date'];

}



/* delete messages older that 60 seconds*/

if((time()-$_SESSION['chat_time_delete'])>60 )

{

$query = "DELETE FROM ".$tableName." WHERE (NOW()-date)>60";

mysql_query($query,$connection);

$_SESSION['chat_time_delete']=time();

}



mysql_close($connection);

?>

We can see session variables initialization: chat_time is the time in which you entered the chat room or of the last message received, while chat_time_delete is the time in which you last deleted a message.
The scripts work this way:

  • connect to the database
  • retrieve the chat room table name using the chatRoomId request variable and the getChatTableName() function
  • query the DB searching for messages not yet received (basing unpon the time of last message received, and at the end of the loop we have a new value for chat_time, that is the last received message time
  • (because) once received messages are useless (a user after connection never received messages of the past), the script delete messages older than 60 seconds

Of course you can format as you like the message board.

At the end we find the sender.php page, that is wrapped in an HTML iframe (because every submission must not cause the entire page reload):



<?php



/***************+ DB variables *****************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********************* NOME TABDELLA CHAT ROOM **************************+*/

function getChatTableName($connection,$chatRoomId)

{

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}





if($_POST['action']=="send")

if($_SESSION['userid']!="")

{

$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selecting chat room.";

exit();

}



$query = "INSERT INTO ".$tableName."(user,message,date) VALUES(\""

.$_POST['userid']."\",\""

.htmlentities(htmlspecialchars($_POST['message']))."\",NOW())";



mysql_query($query,$connection);



}

?>



<body onload="document.msgForm.message.focus();">



<form name="msgForm" action="sender.php" method="post">

<input type="hidden" value="send" name="action"/>

<input type="hidden" value="1" name="chatRoomId"/>

<input type="text" name="userid" value="<?=($_POST['userid']=="")?"guest":$_POST['userid']?>" size="10" />

<input type="text" name="message" style="width:400px" maxlength="1500"/>

<input type="submit" value="invia"/>

</form>

</body>



<?php

mysql_close($connection);

?>

This page simply prints out a web form (in which users insert their nick name -in this version without a check- and the message) and -consequently to the submission- insert the message in the DB, that will be outputted by the timer.js routine.

This will be your final result:

You can read the full tutorial here.

Hopefully this tutorial will be useful to you.

Will the Web be OpenID Compatible by 2009?

Tagged:  

We all would love for all websites to be OpenID compatible. This is looking like a real possibility as more and more companies have announced their support for the standard. Big companies supporting the standard include Google, Microsoft, Yahoo and IBM.

With the support of these large companies we should start seeing more and more OpenID support this year and, if things go right, we may see the majority of big sites going to the standard by the end of 2009.

Over at profy.com they have posted a very good article about Heavy Hitters Jumping on the OpenID Bandwagon. Below is an excerpt from the post.

OpenID technology is a viable way to make handling your online identities easier and more secure. It has been slowly gaining momentum, helped recently by beleaguered company Yahoo's adoption of an OpenID style log in for its many web properties. OpenID got another boost recently when a slew of heavy hitters finally decided to jump on the OpenID bandwagon.

In addition to Yahoo, the OpenID Foundation's board can now count Microsoft, Google, IBM and VerisSign among its board members and supporters. That's fantastic news for the web user like myself who is confounded by far too many log in identities and passwords. OpenID simplifies the task of not only remembering your log in for a site, but for keeping the log in(s) secure as well.

You can read the full post here.

I personally can't wait to see OpenID implemented on more major sites (I'm still waiting for Digg to add support). Since we at Ajaxonomy think that OpenID is a very important thing we have included it in our open blogging and commenting systems. So, hopefully by 2009 everyone will be using OpenID!

Hack the Day Away with Google

Tagged:  

If you are in the Mountain View area you can attend a "Hackathon" with Google on Friday, February 29th from 2pm - 10pm (there are two sessions one from
2pm - 5:30pm and another from 6pm - 10pm). This "Hackathon" is centered around Ajax development and is a great time to learn the below API's from the experts.

Google Gears [http://code.google.com/apis/gears/]
Google AJAX Search/Feeds [http://code.google.com/apis/ajaxsearch/]
Google Gadgets [http://code.google.com/apis/gadgets/]
Google Maps [http://code.google.com/apis/maps/index.html]

There will be a quick over view of the API's before the "Hackathon" starts. A few other things that all of we developers like is that there will be free food, prizes and schwag! Also, make sure to bring your laptop as laptops will not be provided.

You can read more about the event here.

To RSVP your spot click here.

Yahoo! Live and It's API

Tagged:  

Amidst all the news swirling around about a hostile Yahoo! takeover, and the battle of the titans (Microsoft & Google), Yahoo! has released a new service - Yahoo! Live - a personal live streaming video service. [read more about Yahoo! Live at their blog]

Yahoo released an API [a set of Web Services and a couple of embeddable Flash objects] along with this new service. With this API, you can:

  • Find out who's broadcasting right now
  • Get data about past broadcasts
  • See snapshots of past broadcasts
  • Embed live video in your blog or web page

Do keep in mind that the service is currently in limited beta and is not always available.
You may get a message stating "Whoa! Yahoo! Live is an experimental release - we can tell you like the experiment! We're tuning now. Refresh, wait a few seconds, or click here to try again."

Read more about the Yahoo! Live API at the Yahoo! Developer Network and be sure to check out the Yahoo! Live Randomizer demo using REST/JavaScript.

del.icio.us Spy - New Features

Tagged:  

Ajaxonomy's del.icio.us Spy has received quite a positive response around the blogosphere, however, there is always room for improvement. So, having read some comments from people we have decided to make some of the improvements that where in these comments.

The improvements and new features can be found below:

Improved Filtering: The previous version filtered links based on the title of links. The new version filters links based on the links del.icio.us tags.

Submitter User Id: The new version displays the user id of the submitter of the link. This allows for users to view other links from users that they think provide interesting links.

Save For Later: The application now has a Save For Later feature which puts the links that the user thinks are interesting into a temporary holder, so he can go back later and investigate the link. If they like the link they can permanently save it using del.icio.us or another social site.

We hope that you continue to find the del.icio.us Spy useful and would love to hear any additional feedback that you have.

You can get to the application from the Ajaxonomy Labs section of this site (on the right side bar) or you can go to the application here.

Web-based PDF Viewer

Have you ever wanted to make a PDF available by embedding it into a web page? Well now you can with Vuzit.

Below is how the makers of the application describe it.

Vuzit is a web-based universal office document viewer you can embed in any web page to help maintain consistent branding and site navigation. It provides document security and increases revenue by improving accessibility and user experience.

One of the biggest advantages is the protection of stolen data. It makes it more difficult to steal content as it can't be downloaded.

The below code is an example of how you would code a basic viewer.

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <link href="http://vuzit.com/stylesheets/Vuzit-2.1.css" rel="Stylesheet" type="text/css" />
    <script src="http://vuzit.com/javascripts/Vuzit-2.1.js" type="text/javascript"></script>

    <script type="text/javascript">
      // Called when the page is loaded.  
      function initialize()  {
        
        vuzit.Base.apiKeySet("ApiKey");
        var viewer = new vuzit.Viewer(document.getElementById("vuzit_viewer"));
        viewer.setUrl("http://www.welcomingcenter.org/documents/PMP.pdf", { zoom: 1, page: 2 });
      }
    </script>

  </head>
  <body onload="initialize()">
    <div id="vuzit_viewer" style="width: 650px; height: 500px;"></div>
  </body>

Currently the API only supports PDF files, but more formats will be added in the near future.

You can get more information and get more code samples at vuzit.com

Prototype 1.6.0.2 Cheat Sheet

Tagged:  

A new cheat sheet was posted today over at the Prototype blog that is current with all the updates in the recent release of Prototype version 1.6.0.2. Kangax, the author of the cheat sheet, even color coded deprecated 1.6 methods in red.

In the event that this is the first time you've heard of the Prototype 1.6.0.2 release, it happened a few days ago. It contains some bug fixes and performance enhancements, as well as official support for Opera 9.

Click here to read about [and download] the cheat sheet.

Ajaxonomy's del.icio.us Spy - Released!

Tagged:  

You are probably familiar with Digg Spy, but I was very surprised when I found out that there was no similar application for del.icio.us (if you are not familiar with del.icio.us it is a great social bookmarking site).

So, we at Ajaxonomy we decided to make our own del.icio.us spy application. The application allows you to see the latest bookmarks being added to del.icio.us so that you can find great new sites. The application also includes links to help make it easy to share what you find with others.

The application allows you to filter results (i.e. type in "web" and you will only see links containing the word web) and to be notified (via sound) when new items are added. The application also allows you to pause the items that are shown so if you find something you like you can see it for a while.

You can go to the application by clicking here. The application will also be available in the Ajaxonomy Labs section on the right bar of this blog.

As with all the applications in the Ajaxonomy Labs section, this application is open source and you can download the source code here.

Cornerz v0.2 - A Canvas/VML jQuery Plugin

Jonah Fox has released a jQuery Plugin that will add those coveted curvy corners to your site with the use of Canvas/VML.

Usage:
$('.myclass').curve(options)

Options include:
* radius
* borderWidth
* background
* borderColor
* corners ("tl br tr bl"). Specify which borders to draw

Example JavaScript

$('h1').cornerz({radius:40, borderWidth: 0, corners: "tl"})

Example HTML

<h1 style='margin-top: 0px;'>Cornerz v0.2</h1>

Result

The corners are antialiased and load fast, partially do to the script only being 4K - uncompressed. There is a known issue with IE having trouble with odd height values. Jonah's workaround is to use padding-bottom:1px for elements with odd heights.

* Tested on :
- IE6 XP/Vista
- IE7 XP/Vista
- Firefox 2 Ubuntu/Windows
- Safari 3 Windows
- Opera 9 Windows/Linux

Visit the Cornerz homepage to view some demos or click here to see the source.

OpenID: Do you Yahoo!?

Yahoo! has just announced that it would begin supporting OpenID 2.0 technology for both yahoo.com and flikr.com by the end of the month.

Yahoo!’s initial OpenID service, which will be available in public beta on January 30, enables a seamless and transparent web experience by allowing users to use their custom OpenID identifier on me.yahoo.com or to simply type in “www.yahoo.com” or “www.flickr.com” on any site that supports OpenID 2.0.

Full Press Release

With the addition of 248 million Yahoo! users, the OpenID user community essentially triples in size (going from an estimated 120 million users to 368 million).

More information regarding Yahoo!'s OpenID support can be found here.

Syndicate content