Tutorial details:
Written by: Louis Simpson
Difficulty Level: Advanced
Requirements: Flash MX
Topics Covered: Object, Array, XML, WDDX
Assumed knowledge: Variables, Objects, Methods, Event Handlers, PHP…

Download Source

WDDX allows developers to serialize data types in a standard format from any platform. These serialized WDDX objects can be passed from platform to platform and be deserialized to recreate the original object structure in the new environment.

What does all this mean? Let's say we have a PHP script that is used to query a database table and return records. It would be nice to be able to use this functionality to return the query results to Flash MX. Using WDDX we can achieve this quite easily. I kind of see this as the open source flash remoting. I decided to write this tutorial to show how easy it is to grab data from a MySQL database and create a Flash MX recordset from it using this simple technology.

There are a few things you will need in order to follow along. First you will need a server capable of running PHP with WDDX support and a MySQL database, although if you know enough about what you are doing you could use whatever data source you wanted.

If you are running PHP on windows WDDX support is already included at least in version 4.3.0 it is. If you are on linux and a shared host, your host will have to make sure PHP was compiled with -enable-wddx. If you maintain your own server you can compile your PHP with wddx support. You will also need the file wddx_mx.as by Branden Hall, and the NetServices.as and DataGlue.as files that are included with the free Flash remoting components from Macromedia which can be found at
http://www.macromedia.com/software/flashremoting/downloads/components/ .

Okay so once you have all that sorted out, let's create a MySQL database and a table and put some data in it. First create a new database called "flash", then log into the MySQL console and paste the following into the command line.

CREATE table test (
id int(11) unsigned not null auto_increment primary key,
       First_Name varchar(50),
                   Last_Name varchar(50),
                  Email varchar(50),
              City varchar(50)
);
INSERT INTO test SET First_Name='John', Last_Name='Williams', Email='jw@somedomain.com', City='Ventura';
INSERT INTO test SET First_Name='Pete', Last_Name='Williams', Email='pw@somedomain.com', City='Ventura';
INSERT INTO test SET First_Name='Larry', Last_Name='Jackson', Email='lj@somedomain.com', City='Camarillo';
INSERT INTO test SET First_Name='Billy', Last_Name='Dee', Email='bd@somedomain.com', City='Ojai';
INSERT INTO test SET First_Name='Jackson', Last_Name='Smith', Email='js@somedomain.com', City='Santa Paula';
INSERT INTO test SET First_Name='Pam', Last_Name='Jones', Email='pj@somedomain.com', City='Ojai';
INSERT INTO test SET First_Name='Sherri', Last_Name='Jackson', Email='sj@somedomain.com', City='Ventura';
INSERT INTO test SET First_Name='Louie', Last_Name='Jones', Email='lj@somedomain.com', City='Camarillo';
INSERT INTO test SET First_Name='Jim', Last_Name='Smith', Email='js@somedomain.com', City='Oxnard';
INSERT INTO test SET First_Name='Ronald', Last_Name='Smith', Email='rs@somedomain.com', City='Ojai';
INSERT INTO test SET First_Name='Lucy', Last_Name='Jones', Email='lj@somedomain.com', City='Santa Paula';
INSERT INTO test SET First_Name='Freddy', Last_Name='Johnson', Email='fj@somedomain.com', City='Ventura';


Now let's look at our PHP scripts. Create a new php script and save it as flashServer.php

In it place the following code.

<?php
header("Content-type: text/xml");

/*
Check for existence of the new $GLOBALS array
If its found get the raw wddx packet from the array or
Else get it from the variable $HTTP_RAW_POST_DATA
*/

if($GLOBALS['HTTP_RAW_POST_DATA']) {
        handleWDDX($GLOBALS['HTTP_RAW_POST_DATA']);
}
else {
        handleWDDX($HTTP_RAW_POST_DATA);
}



/*
Deserialize the wddx packet and run the function specified
Passing the parameters from flash.
*/

function handleWDDX($arg) {
        $foo = wddx_deserialize($arg);
        $foo['funcName']($foo['parameters']);
}


/*
getPersonById()
Simply retrieves data about a person based on an id passed from flash
*/

function getPersonById($args) {
        $db = mysql_connect("localhost", "root", "");
        mysql_select_db("flash");
        $result = mysql_query("SELECT * from test WHERE id = ".$args['id']);
        $row = mysql_fetch_assoc($result);
        $packet_id = wddx_packet_start();
        $person = $row;
        wddx_add_vars($packet_id, "person");
        $packet = wddx_packet_end($packet_id);
        print $packet;
}

/*
getPersonById()
Simply retrieves list of people. If the array fields is
Populated only select those fields or else select all fields
Create a variable to hold the column names and an array to
Hold the records and return them to flash.
*/

function getPersonList($args) {
        $db = mysql_connect("localhost", "root", "");
        mysql_select_db("flash");
        $sql = "SELECT ";
        if(!is_array($args['fields'])) {
                $sql .= "*";
        }
        else {
                $sql .= implode(",", $args['fields']);
        }
        if($args['limit']) {
                $sql .= " from test limit ".$args['limit'];
        }
        else {
                $sql .= " from test";
        }
        $result = mysql_query($sql);
        $packet_id = wddx_packet_start();
        $people = array();
        $i=0;
        while($row = mysql_fetch_assoc($result)) {
                if($i == 0) {
                        $cNames = array_keys($row);
                }
                $i++;
                $out = array();
                foreach($row as $key => $val) {
                        $out[] = $val;
                }
                array_push($people, $out);
        }
        wddx_add_vars($packet_id, "cNames");
        wddx_add_vars($packet_id, "people");
        $packet = wddx_packet_end($packet_id);
        print $packet;
}

?>

If you made it this far, you realize this takes a raw wddx packet from flash deserializes it and runs the specified function while passing the correct parameters.

Now let's setup the flash side of things.

For this example we will fill a listBox with people from the database using the remote procedure getPersonList(), when an item is selected we will retrieve all information for that person using getPersonById().

Put a listBox on the stage and set its instance name to "myList", place two dynamic text boxes each with a scroll bar on the stage. Give them the instance names "detailText" and "debugText". Set them to multiline and show borders, set detailText to render as html.

Place the following actionscript in frame 1:

//Include necessary libraries
#include "NetServices.as"
#include "wddx_mx.as"
#include "DataGlue.as"

//The url to the gateway script.
var myURL = "http://www.irq11.com/~louie/wddx/flashServer.php";

//Create a new object to serialize and send to our server
myObj = {};

//Assign the function to run on the server
myObj.funcName = "getPersonList";

//Set up the parameters array
myObj.parameters = {};

//Send which fields to select
myObj.parameters.fields = ["id", "First_Name", "Last_Name"];

//Set up the new WDDX object
myWDDX = new WDDX();

//Serialize our object to send to the server
myXML = myWDDX.serialize(myObj);

//Set the content type so PHP won't choke
myXML.contentType = "text/xml";

//Send the packet
myXML.sendAndLoad(myURL, myXML, "POST");
debugText.text = "Sending wddx packet \n==================\n" + myXML+"\n==================\n";

myXML.onLoad = parseList;


function parseList() {
        debugText.text += "Receiving wddx packet \n==================\n" + this+"\n==================\n";
       
        //Deserialize the return packet
        retVal = myWDDX.deserialize(this);
       
        //Create a new Recordset with the column names sent back from PHP
        myRS = new RecordSet(retVal.cNames);
       
        //Set the contents of the recordset to the array people coming from PHP
        myRS.setData(0,retVal.people);
       
        //Glue the recordset to the listbox
        DataGlue.bindFormatStrings (myList, myRS, "#Last_Name#, #First_Name#", "#id#");
}

//The change handler for the list box
getDetail = function() {
        //Create a new object to serialize and send to our server
        myObj = {};
       
        //Set up the function to run
        myObj.funcName = "getPersonById";
       
        //Set up the parameters array
        myObj.parameters = {};
       
        //Set the id to pass to the function
        myObj.parameters.id = myList.getSelectedItem().data;
       
        //Set up the new WDDX object
        myWDDX = new WDDX();
       
        //Serialize our object to send to the server
        myXML = myWDDX.serialize(myObj);
       
        //Set the content type so PHP won't choke
        myXML.contentType = "text/xml";
       
        //Send the packet
        myXML.sendAndLoad(myURL, myXML, "POST");
       
        debugText.text = "Sending wddx packet \n==================\n" + myXML+"\n==================\n";
        myXML.onLoad = parseDetail;
}

function parseDetail() {
        debugText.text += "Receiving wddx packet \n==================\n" + this+"\n==================\n";
        detailText.htmlText = "";
       
        //Deserialize the return packet
        retVal = myWDDX.deserialize(this);
       
        //Loop through the return object and setup a display for our
        //detailText field
        for (var i in retVal.person) {
                detailText.htmlText += "<b>"+i+":</b> "+retVal.person[i]+"\n";
        }
}


Well I hope that this shows some of the things that one could achieve with Flash MX and PHP, I for one think this is the start of something really cool. A working demo of this can be found at:
http://www.irq11.com/~louie/wddx/peopleServer.html

And the source files are here:
http://www.irq11.com/~louie/wddx/peopleServer.zip
or
Here