Flash Guestbook V2

Creating a guestbook in Flash using PHP script and a MySQL database

Setting up the database

You will need to have access to a server running PHP and MySQL. If you use another database, replace the MySQL database functions that I use in the PHP script with the database functions for the other database i.e. PostgresSQL, MSSQL.

First create two tables in the database:

# This table will hold the guestbook entries.
# Table structure for table `flashgb`
#

CREATE TABLE flashgb (
id int(4) NOT NULL auto_increment,
name varchar(20) NOT NULL default '',
email varchar(30) NOT NULL default '',
homepage varchar(50) NOT NULL default '',
comment text NOT NULL,
date datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id)
) TYPE=MyISAM;

# This table will hold information on users allowed to access the guestbook administration
# Table structure for table `flashusers`
#

CREATE TABLE flashusers (
id tinyint(3) unsigned NOT NULL auto_increment,
username varchar(20) NOT NULL default '',
password varchar(20) NOT NULL default '',
email varchar(50) default NULL,
PRIMARY KEY (id),
UNIQUE KEY username (username)
) TYPE=MyISAM;

The Flash movie (swf)

The Flash timeline
The Flash movie (swf) will interact closely with the PHP script used to query the database i.e. buttons sumitting data to the script and Flash variables incremented/decremented based on values set by the script.

The movie has a five layers: a background (layer 4 in the image below) which is just a simple gray square, the content (layers 2, 8 and 5 in the image below) which have the status fields, input fields, buttons etc. of the guestbook, and the frame actions (layer 6 in the image below) which has all the actionscripts associated with frames in the movie.

Flash timeline rollover: all the frame actions and frame visuals.

A closer look at selected guestbook functions

The FLA file that accompanies the zip archive of this tutorial will have all the actionscript for the frames and buttons. The complete PHP script will be on the last page.

The View Entries button:

This button is present on many frames. It tell the PHP script that the state of the guestbook is 'main'. When the PHP guestbook is in the main state the idnum variable is set to zero (0) and the total number of entries in the guestbook are retrieved from the database. These two values are reported to the flash movie.

Actionscript code:---------------------------------------------------------------
on (release) {
gotoAndStop (2);
entries = "loading data ...";
loadVariables ("new.php?"+int(Math.random*100000)+"&state=main", "", "POST");
entries.scroll = 1;
}
--------------------------------------------------------------------------------

PHP Code

.
.
.
case 'main': // Inform user how many entries are in the guestbook
 
// Send data to the Flash movie
print '&idnum=0&totalcount='.urlencode($totalcount).'&entries='.urlencode("Total guest book entries ").
urlencode($totalcount);
.
.
.

Although the PHP script is passed an id number of zero, this is actually not the id number of the guestbook entry saved in the database. Since I have the ability to delete entries in the guestbook, I know that the id numbers would not stay in sequential order, but I want my foward and back buttons to work that way. I decided to use the mysql_data_seek function to save myself the trouble of retrieving the id numbers of entries in the guestbook.

The function mysql_data_seek (result_identifier, row_number) returns a specified row number from the results returned by mysql_query. The row number starts at zero and ends at the total number of rows found minus one. This means that if the total number of rows returned for my mysql_query is five, then mysql_data_seek(result, 0) will return the first row found in the result, mysql_data_seek(result, 4) will return the fifth row.

The back and foward button:

Both buttons will print 'no previous/further entries' when there are no more guestbook entries to display. The buttons tell the PHP script that the state is 'view' and passes an id number.

Actionscript code:--------------------------------------------------------------
// back button
on (release) {
idback = idback-1;
if (idback<0) {
entries = "No previous entries.";
idnum = 0;
} else {
entries = "loading data ...";
loadVariables ("new.php?"+int(Math.random*100000)+"&state=view&id="+idback, "", "POST");
entries.scroll = 1;
}
}
 
// foward button
on (release) {
entries = "loading data ...";
loadVariables ("new.php?"+int(Math.random*100000)+"&state=view&id="+idnum, "", "POST");
entries.scroll = 1;
}
--------------------------------------------------------------------------------

PHP code:

.
.
.
mysql_data_seek($result,$id);
 
if($id < $totalcount){
$n=++$id;
$q=mysql_fetch_array($result);
 
$name=$q["name"]; //getting each variable from the table row
$email=$q["email"];
$url=$q["homepage"];
$comment=$q["comment"];
$date=$q["date"];
 
// Send data to the Flash movie
$entry .="Name: $name \n";
$entry .="Email: <a href=\"mailto:$email\">$email</a> \n";
$entry .="Homepage: <a href=\"$url\">$url</a> \n";
$entry .="Comments: $comment \n";
$entry .="Date: $date \n";
 
print "&entries=".urlencode($entry).'&idback='.urlencode($cid).'&idnum='.urlencode($n);
.
.
.

An explanation of the login process:

Frame 5 has the login form: a dynamic text status field, two input text fields and a login button.

The actionscript on the login button, posts the password and the username to the PHP script.

Actionscript code:---------------------------------------------------------------
on (release) {
if (username ne "" && passwd ne "") {
gotoAndPlay (6);
status = "Beginning Login Process.. Please Hold";
// The next line calls the login.php script. And returns the results from it to the movie.
loadVariablesNum ("new.php?"+int(Math.random*100000)+"&username="+username+"&passwd="+passwd+"&state=login", "0", "POST");
} else {
status = "Please enter a User Name/ Password";
}
}
--------------------------------------------------------------------------------

Frames 6 and 7 also display the login form and have frame actions: if the PHP script returns the CheckLog (successful login) value goto frame 8, otherwise continue checking.

Actionscript code:---------------------------------------------------------------
// Checks to see if the variable CheckLog has a value.
//If it does the login was successful - If not it was not.
if (CheckLog ne "") {
gotoAndPlay (8);
} else {
gotoAndPlay (6);
}
---------------------------------------------------------------------------------

The status field will display the appropriate message if there is an error or the login was successful etc.

Deleting an entry
After clicking on the delete button, you goto another frame and must confirm that you want to delete an entry.

Actionscript code:---------------------------------------------------------------
// This action is on the frame
stop ();
status = "Delete data for entry "+idback+" ? /" +upid;
 
// This is what happens when the confirmation button is clicked
on (release) {
gotoAndPlay (24);
status = "Beginning Delete Process.. Please Hold";
loadVariablesNum ("new.php?"+int(Math.random*100000)+"&state=delete&upid="+upid, "0", "POST");
}
---------------------------------------------------------------------------------

The status field will display something similar to 'Delete data for entry 1 ? /2,' meaning the second entry out of all entries in the guestbook will be deleted, the actual id number of this entry is 2. Only the actual id number (upid) is passed to the PHP script. I only display it for error checking, once you are sure the delete process is working correctly you can remove it.

The Guestbook script

Complete PHP code

PHP Code:

<?php
// Connects to the database.
$db = mysql_connect("localhost", "username", "password");
mysql_select_db("database",$db) or die ("Unable to connect to database");
 
// SQL query to retrieve data
$result = mysql_query("select * from flashgb order by id");
$totalcount= mysql_num_rows($result); // Total number of entries in the guestbook
 
switch ($state) {
 
case 'submit': // Add data to the database
 
$entry=mysql_query("INSERT INTO flashgb (name,email,homepage,comment,date)
VALUES ('$name','$email', '$homepage','$comments',NOW())");
 
// After adding data go back to the first page of the guestbook
if($entry){ Header("Location: version.html"); }
 
break;
 
case 'view': // View entries in the guestbook
 
if($id >= 0){
$cid=$id; // current record
mysql_data_seek($result,$id);
 
if($id > $totalcount){
$n=++$id; // next record
$q=mysql_fetch_array($result);
// Assign data retrieved from the table row to variables
$name=$q["name"];
$email=$q["email"];
$url=$q["homepage"];
$comment=$q["comment"];
$date=$q["date"];
 
// Format data to be sent to Flash
$entry .="Name: $name \n";
$entry .="Email: <a href=\"mailto:$email\">$email</a> \n";
$entry .="Homepage: <a href=\"$url\">$url</a> \n";
$entry .="Comments: $comment \n";
$entry .="Date: $date \n";
 
// Send data to the Flash movie
print "&entries=".urlencode($entry).'&idback='.urlencode($cid).'&idnum='.urlencode($n);
 
}else{ print '&entries='.urlencode("No further entries").'&idback='.urlencode($totalcount).
'&idnum='.urlencode($totalcount); }
 
}
 
break;
 
case 'main': // Inform user how many entries are in the guestbook
 
// Send data to the Flash movie
print '&idnum=0&totalcount='.urlencode($totalcount).'&entries='.urlencode("Total guest book entries ").
urlencode($totalcount);
 
break;
 
case 'login': // Validate username and password used to access guestbook administration
 
$findusr = mysql_query("SELECT id FROM flashusers WHERE username = '$username' AND password = '$passwd'");
 
if(mysql_num_rows($findusr)) {
print '&CheckLog='.urlencode("1").'&status='.urlencode("Success Login Complete");
} else {
print '&status='.urlencode("There was a problem with your login.");}
break;
 
case 'view2': // Retrieve data for individual entries in the guestbook for possible update
 
if(!$id){ $id=0;} // Default: if the $id is not set, retrieve data for the first guestbook entry
 
if($id >= 0){
$cid=$id;
mysql_data_seek($result,$id); // Find the first row of data in the results retrieved
 
if($id < $totalcount){
$n=++$id;
$r=mysql_fetch_array($result);
$rlid=$r["id"];
$name=$r["name"]; //getting each variable from the table row
$email=$r["email"];
$url=$r["homepage"];
$comment=$r["comment"];
$date=$r["date"];
 
// Information being sent back to the Flash movie
print '&status=Showing data for entry '.urlencode($cid).'&name='.urlencode($name).'&email='.urlencode($email).
'&homepage='.urlencode($url).'&comments='.urlencode($comment).'&idback='.urlencode($cid).
'&idnum='.urlencode($n).'&upid='.urlencode($rlid);
 
}else{ print '&status= No further entries.&idback='.urlencode($totalcount).'&idnum='.urlencode($totalcount).
'&name= &email= &homepage= &comments= '; }
 
}
 
break;
 
case 'update': // Save updated guestbook data to the database
 
$changerec=mysql_query("UPDATE flashgb SET name='$name', email='$email',
homepage='$homepage', comment='$comments' WHERE id='$upid'");
 
if($changerec){
print '&UpLog='.urlencode("1").'&status='.urlencode("Success Update Complete");
} else {
print '&status='.urlencode("There was a problem updating entry ".$upid);
}
 
break;
 
case 'delete': // Delete guestbook data from the database
 
$delrec=mysql_query("DELETE from flashgb where id='$upid'");
 
if($delrec){
print '&DeLog='.urlencode("1").'&status='.urlencode("Success Delete Complete");
} else {
print '&status='.urlencode("There was a problem deleting entry ".$upid);
}
 
break;
 
}
?>

See it in action. ¦ Flash Guestbook Version 2 archive

** You will need the WinRAR program to unzip this archive. It is in rar format not zip.