Building the Bulletin Board
You're going to need the source files for this section of the tutorial as we're not going to build this application from the ground up; rather we'll deconstruct a completed version together, allowing you to see how the system works. The Bulletin Board, as I've implemented it, uses a MySQL database with the structure as shown below. If you don't understand what it means, don't worry, this structure is really just useful for anyone who actually wants to implement this system, which you are free to do, commercially or non-commercially, so long as you credit me :)

CREATE TABLE posts (
  id tinyint(4) NOT NULL auto_increment,
  name varchar(100) NOT NULL default '',
  email varchar(100) NOT NULL default '',
  url varchar(100) default NULL,
  message text NOT NULL,
  date datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (id)
) TYPE=MyISAM;

Place the BulletinBoard.php file in the services folder. Now open up BulletinBoard.php and have a look. This file is used to read existing entries to and create new entries to the board on the backend. It contains the class definition, the constructor, the doPost and doRead remote methods as well as a helper 'escape' method.

Recall that the power of remoting is allowing Flash to connect to classes and reference methods therein as local methods. This means that when we connect to the BulletinBoard class within Flash we get access to the doPost and doRead methods of that class from Flash.
The constructor method, as with our simple example above defines the methodTable which lists information about all methods in this class (in this case the doPost and doRead methods). We connect to the database immediately inside the constructor since we are going to need a MySQL connections for all of our remote methods anyway. The constructor is a good place to initialize variables, create connections and similar tasks, in addition to being the place where the methodTable is defined.

The doPost method takes in an associative array (Object passed from Flash) and pumps the information in that array into the database, returning a simple 'success' or 'fail' message (in the form of an associative array) for debugging at the other end.

The doRead method takes two arguments which are used in retrieving results from the database rather than pumping information into it. Notice that we are simply returning the result directly from mysql_query. In Flash we will receive this result as an instance of mx.remoting.RecordSet. That RecordSet will then have methods like getItemAt, filter, sortItemsBy and all sorts of useful things. The RecordSet object can then be bound to the v2 components like the DataGrid component or the ComboBox and viewed as is. Sure beats XML, doesn't it ? (remember xml.firstChild.childNodes[i].nodeValue?)

What's really happening behind the scenes is that amfphp detects the returned result and loads an appropriate driver for it. This driver is written specifically for the database system we are using. amfphp recognizes MySQL, PostgreSQL, Oracle, PEAR::DB, SQLite, and whole bunch of other database types automatically. Then it encodes it in AMF using a special format and sends it back to Flash, which maps it to mx.remoting.RecordSet. amfphp's database drivers are optimized for speed, so if you need to send back large amounts of complicated data, send it directly as a RecordSet for a nice speed boost (it's simpler anyway).

Note also the NetDebug::trace statements in both the doRead and doPost methods. In Flash, you can use the trace statements to view things in the trace window. With amfphp, you can achieve a similar result with NetDebug::trace. You will get a new line in the NetConnection debugger called 'Trace' with an icon that looks like two tin cans along with the results of the remote call. By clicking on it you will see the contents of the trace stack. NetDebug::trace can be used to send back strings, like trace, and also objects and arrays. Here I'm tracing the SQL strings so if they are malformed I'll know it immediately. It's also very useful to trace mysql_error to get debug info in case your SQL is wrong. Of course you wouldn't want to deploy your app and still have SQL showing up for everyone to see! You can open up the gateway.php file and set PRODUCTION_SERVER to true to disable remote tracing; this is similar to the 'Omit trace' checkbox in the Flash Publish settings.

Finally we have an escape method which simply escapes an argument (add slashes before the quotes). This is a private local method so it's not defined in the methodTable. PHP comes with a feature called 'magic quotes' which escapes quotes (') so you can insert variables with quotes in them in a database directly. amfphp does not enforce magic quotes (it acts as though magic quotes were off), so it's important to escape data before putting it in the database, otherwise names like O'Conor and D'Alembert will cause an error.

Now let's look at the ActionScript. The BulletinBoard.fla file contains only one line of ActionScript; the rest of the code is in BulletinBoard.as. This ActionScript file may look a little daunting at 280 lines of code, but it's mostly comments and whitespace so don't despair. The bulk of the code is similar to the simple example given above so that little explanation is warranted. First we import the ActionScript packages for successful Service establishment and debugging. In the init method, we define and connect to our Service. Right below we define local functions which call the corresponding remote methods, and right below those we write the result handlers. Pretty simple huh? You can figure what each method does by looking at the prefix: 'do' call remote methods, 'handle' receives remote results, and 'on' handles UI events. Below the interesting Remoting stuff there's a lot of boring UI code, which you should have probably become accustomed to by now.

Let's look at the doPost method. All it does is take an info object and passes it along to Remoting. This info object is created by the onPost method. It combines the values of the text field into an object and then just passes that object to the doPost method of the service object, which is of course just a link to our external MessageBoard.php file, so the message object we establish is piped through to the PHP file which reads out the values and stores them in our database. See how simple and brilliant it is? No need to convert the data to strings and then back at the other end, no need to serialize the data. No work period. Just pass and smile. If you take a proper look at the handleDoPost method you'll see that all it does is hide the post interface and refreshes the main datagrid.

(At this point I should say that I feel this tutorial is a major divergence from the standard slow and stepwise approach I take to teaching ActionScript in all my other content. Comments on how well you understood this tutorial - after you've read it all of course - would be much appreciated.)

Now for the really interesting part. Take a look at the doRead method. What it does is simply call the remote function and gets back a RecordSet with 10 items. In handleDoRead, all we do is set the dataProvider of the DataGrid to the returned RecordSet. That's all we need to do to show our data. That's right... All that cool functionality, the DataGrid with the headers, the draggable columns, the clickable rows, the sortable data... That's one line of code. (Did I mention I love Flash Remoting?) In the initUI method I had prepared the columns of the DataGrid. The column names are the same as the name of the SQL table columns.

Here I've only shown three of the 6 columns amfphp sent back. The rest of data is not shown, but it's still stored in the datagrid's dataProvider. I set up a listener for the datagrid's change event, the onDgChange method. What it does is inspect the hidden data for the currently selected row and fills in the TextArea below with all of the data. Again the names of the data keys is inherited from the names of the SQL table columns.

So that's it folks; my longwinded and rushed introduction to Flash MX Remoting (using PHP). Over 5000 words; that's my record I think. Take a look at the amfphp documentation for more info, especially on how to debug your services. As always, please post questions related to this topic or this tutorial on the relevant board (try the Flash Remoting board!) in the Forums section of the site for assistance. Comments and error corrections regarding this tutorial are welcome. Have a great day!

Jesse Stratford is the Co-Master of ActionScript.org and a freelance Flash developer and teacher. He is based in Australia and enjoys all things Flash.

NB: If you have comments or feedback please feel free to email me, but please do not email me Flash questions; the forums are provided for that purpose and you will get a faster answer by posting you question there.

If you have found this tutorial helpful, I hope that you will take 30 seconds to visit The Hunger Site where, with just one click you can make a free donation of food to a starving person in a third-world country. We do not benefit financially from this action; it is purely an act of charity.
This tutorial is protected by International Intellectual Property Rights laws and may not be reproduced or redistributed in full or part, without the prior written consent of the author. Unauthorized reproduction of this tutorial or its contents may result in prosecution. I've worked hard on this tutorial, please don't steal it.