- Home
- Tutorials
- Flash
- Intermediate
- Flash MX (PHP) Remoting

Page 2 of 3
A Stepwise Process
Here's a brief outline of how we can communicate directly between Flash
and PHP Remoting. Each of these aspects will be covered in more detail
later in the tutorial, but it's good to have an overall view of where
you're headed before you start.
To send a message between Flash and PHP (let's say we're going to call
a PHP function for this example), a number of steps are required.
Before we can do anything we need to create a local 'Service' object in
our Flash movie. When creating this object, we supply the location of
the gateway.php file as well as the name of the remote service we want
to have direct access to. This object only needs to be created once.
Once the service object is created, we invoke an RPC on the Service and await the results. It's important
to note that (like pretty much every other communication method in Flash)
Remoting is not synchronous - that means when you call your service you
can't expect to get a result returned immediately, nor will Flash wait
for a result before continuing to execute any other actions appearing
after your call. For this reason we are provided with a means of
making 'responders', which are basically event handlers which handle returned
data, but more on that later.
For our Bulletin Board example, when posting a new entry to the board we will send some basic user details such as name and email and the body of the message. When retrieving posts from the board we will send back the same details from PHP to Flash. This could (and has, many times) all be done without Remoting, but Remoting makes the whole process more tightly linked (or tightly-coupled) and easier. Remember, this tutorial is just an indication of the power of Remoting, made for beginners, so don't expect to finish up with a ground-breaking application. That's for you to develop on your own :)
Under the Hood:
So far I've made amfphp sound like some magical system which manages absolutely
everything for you; all you do is shift data around and the rest sorts
itself out. Understanding what's going on behind the scenes is really
important for development purposes, so here's a brief outline. When you
send data through the amfphp gateway, it is analyzed (deserialized) and manipulated
into a compatible data format for PHP, allowing you to read it in PHP
as though it were native data. When you go to send data back from PHP
to Flash the same process occurs but in reverse; the PHP data types are
converted (serialized) to similar Flash data types. Note the keyword in that sentence
was 'similar'.
Flash and PHP are both Object Oriented languages but they aren't identical
in terms of the way they treat data types, (the saying goes "The
great thing about standards is there's so many to choose from").
For our purposes the best example of this is the Object example. An Object
in Flash doesn't translate directly to an Object in PHP, even using the
magic PHP Remoting gateway. The nearest relative to a Flash Object in
PHP is what is called an 'associative array', that is, an array with elements
that are accessed via 'keys' (or alphanumerical names) as opposed to indexes
(numbers). See the arrays tutorial for more on associative arrays. So
when you see me passing Objects into PHP then working with associative
arrays inside PHP, you'll understand why.
Get Started Already!
OK enough definitions, descriptions and introductions, let's get into
some coding. First we're going to discuss the basics of establishing connections
via Remoting and calling functions. Grab this simple example
archive
and place the talkback.php file into the amfphp/services directory. The
services directory is a special directory where you put Flash-enabled
php services.
Now open the 'talkback.php' file, the contents of which look something like this:
<?php
// Create new service for PHP Remoting as Class
class talkback
{
function talkback ()
{
// Define the methodTable for this class in the constructor
$this->methodTable = array(
"returnString" => array(
"description" => "Return a String",
"access" => "remote"
),
"returnNumber" => array(
"description" => "Return a Number",
"access" => "remote"
),
"returnArray" => array(
"description" => "Return an Array",
"access" => "remote"
)
);
}
function returnString ($in) {
return "You said '$in' and I totally agree!";
}
function returnNumber ($in) {
return $in * 10;
}
function returnArray ($in) {
$objVal = $in['foo'];
return array("theKey" => "Your Object contained the value $objVal");
}
}
?>
PHP Remoting is class-based, so if you don't currently write Object Oriented PHP you'd better start if you want to make use of this new service. Each class you create can be accessed as a 'service' within Flash, and each class's methods become functions you can invoke via that service using remote procedure calls (RPCs).
In brief, here's what this file does. First it declares a new class which will be the 'service' we wish to access from Flash. Next we define the 'constructor' for this class (which is the function that is run automatically whenever a new object is instantiated from this class). The constructor has to have the same name as the class. It must establish the associative array known as the methodTable which lists information about each and every method of a class. Importantly, it tells which of these methods can be called from Flash (what you see as 'access' => 'remote'). If access is not set to remote, amfphp will refuse to run the method remotely for security reasons.
The names of the methods are pretty indicative of what they do. The returnString and returnNumber methods each take one argument; a String and Number respectively. The returnArray method takes a Flash-style Object (which as I've mentioned, is equivalent to a PHP associative array), and returns an associative array, which Flash reads in as an Object. But don't take my word for it. Let's see this baby in action!
Leave the 'services' subdirectory and open up the talk.fla file provided. Click on the first frame and double-check that the first line which points to your gateway.php is correct (if you've followed the instructions, this should be http://localhost/amfphp/gateway.php). This file contains configuration options, like the character set you want to use or the location of the services directory. It also gets the amfphp machinery going. With amfphp, you don't point to the services directly; you always talk to your services through the gateway.
Don't look at the rest of the code yet, just test run the movie. If you're setup correctly, your trace window should output the following:
Calling returnString
Calling returnNumber
Calling returnArray
Got result "You said 'Flash Remoting is groovy' and I totally agree!" of type string
Got result "500" of type number
Got result "[object Object]" of type object which contained the following:
theKey: Your Object contained the value bar
If you look back at the 'talkback.php' file you'll get an idea of what's
going on. We're passing values to the PHP methods and they are returning
them, then they are being traced out to the output window.
Now we'll dig up a very useful tool called the NetConnection debugger.
The NetConnection debugger is located on Windows at
C:\Documents and Settings\{Your username}\Local Settings\Application
Data\Macromedia\Flash
{version}\{language}\configuration\WindowSWF\NetConnection Debugger.swf. On OS X it should be in: /Users/{username}/Library/Application Support/Macromedia/Flash {version}/{language}/Configuration/WindowSWF\NetConnection Debugger.swf.
Since it's a very useful tool, you'll probably want to make a shortcut
on your desktop to it so you'll have it handy whenever you need it.
Close the test movie, and double-click on the NetConnection Debugger.swf file to open it. You
should get a new window which pops up. Now test 'talk.fla' (Ctrl+Enter) again but this
time, ignore the output window (the output is the same) and take a look
at the NetConnection Debugger. This window lists communication between
Flash and the installed Remoting service. If everything is going well
you should see eight entries in the 'Events' listing at the left; one
Connect, three Calls, another Connect and three Results. You can click on any event listed
and click the Details tab to see everything that's happening; have a look
around.
This is what's going on behind the scenes to cause that output we saw a
moment ago. The first connection indicates the request made by Flash to
create a Remoting service. Each Call represents a Remote Procedure Call
(RPC) and each Result indicates a value being returned from the method
which was called via the corresponding RPC. The second connection is
triggered when amfphp asks Flash to call another gateway in the future,
one which has the session id appended to the URL; this allows you to
use sessions without cookies. You'll see that we call the three Methods
available in the talkback.php file in the order they are written, and
the results come back in that same order. Note that the Calls and
Results are grouped together, not mixed up. This illustrates what I was
saying before about Flash Remoting being asynchronous; the requests are
sent one after the other, without waiting for a result to be returned.
So how am I tracing the results as they come in? I'm glad you asked
that, let's take a look at the code.
Close the test movie so that you're back to the talk.fla and view the actions on the first frame. Let's go through these actions together.
First we define the gateway url. Next we include import a few ActionScript packages which come with the Flash Remoting Components you installed earlier. To be able to use these packages, I had to place the classes in the library. This is a very important step that people tend to forget. To put the classes in your library in your next Remoting movie, in Flash 8, click Window > Common Libraries > Remoting, or in Flash MX 2004, click Window > Other Panels > Common Libraries. Then drag the 'RemotingClasses' and 'RemotingDebugClasses' symbols on the stage of your movie. You can then safely delete them, they will stay in your library from now on.
mx.remoting.* defines most of the groovy classes we use in Flash Remoting like Service and RecordSet. mx.remoting.debug.* is what makes the NetConnection debugger run. mx.rpc.* contains helper classes like PendingCall and ResultEvent (more on these later). These three lines should be the first things you type in all your Flash Remoting projects. Right after we start the NetConnection Debugger with NetDebug.initialize().
Note: It's been brought to my attention that different versions of the NetServices.as file have different capitalization of the setDefaultGatewayURL string. E.g. setDefaultGatewayURL vs setDefaultGatewayUrl. Since ActionScript.org 2.0 and above are case sensitive, you will need to ensure you are using the right one. You'll get an error if you're not, saying the function doesn't exist.
//Set this to the location of your gateway.php file
var gatewayUrl:String = "http://flashservices/gateway.php";
// Import packages necessary for Remoting debugging and coding
// Note that the Remoting components must be in the library for this to work
import mx.remoting.*;
import mx.remoting.debug.*;
import mx.rpc.*;
//Start the NetConnection debugger
NetDebug.initialize();
Next we define the location of our gateway and establish a Service between Flash and our gateway via HTTP, which is why you need an active web server to test this stuff locally. We need only do this once and the Service will be available until the movie is unloaded. When you want to invoke a method in one of your classes you send a message through the Service ('down the phone line' if you will) and your PHP class executes and sends any response back via the same phone line. The Service class constructor takes three arguments, the gateway url, a seldom used second parameter (usually null), and then the service name.
//Set this to the name of the remote service
var serviceName:String = 'talkback';
// Create PHP Remoting Service
var talkback:Service = new Service(gatewayUrl, null, serviceName);
PHP Remoting looks for a file in the services folder with the same name as the service we request. For instance, in this example, our class is called 'talkback' so it is saved in talkback.php and we request the service called 'talkback' via Flash. If the class is named differently from the file, amfphp won't be able to find it. I also name the reference to the service 'talkback' so that when I invoke methods it's obvious which class I'm talking to.
With the service established we can now invoke methods as though the service were a local Object "talkback.methodName();". Before calling the remote methods, we need to define callbacks so Flash will have something to do with any results which are sent back from that method invocation. What we do is create result functions and fault functions. The result functions are called when a Remoting call works; it always take one argument, the ResultEvent. Inside this object's 'result' lies the result of the remote function. Inside this function we define the actions we want to take place when results are returned from a remote method.
We also define fault functions. Fault functions are called when the remote method ran into a snag; for example, when the remote method doesn't exist or we don't have the permissions required to call it. Fault functions take one argument, the FaultEvent. Inside this object is a 'fault' object which itself contains the all important 'faultstring'. You don't *need* to create fault functions, but I included it here for completeness. You can see faults in NetConnection Debugger anyway.
The next few function definitions inside talk.fla are called 'handleSomething' with a name related to the remote function and tell Flash what to do with results sent back from each of those methods.
// Define result handling code
function handleSimpleReturn(re:ResultEvent) {
trace("Got result \""+re.result+"\" of type "+typeof (re.result));
}
function handleArrayReturn(re:ResultEvent) {
trace("Got result \""+re.result+"\" of type "+typeof (re.result));
trace("It contained theKey: "+re.result.theKey);
}
function handleFault(fe:FaultEvent)
{
trace("There was this fault: " + fe.fault.faultstring);
}
Finally, we call the methods via the service reference we defined within Flash and await the results.
// Call some functions
trace("Calling returnString");
var pc:PendingCall = talkback.returnString("Flash Remoting is groovy");
pc.responder = new RelayResponder(this, 'handleSimpleReturn', 'handleFault');
trace("Calling returnNumber");
var pc:PendingCall = talkback.returnNumber(50);
pc.responder = new RelayResponder(this, 'handleSimpleReturn', 'handleFault');
trace("Calling returnArray");
test = new Object();
test.foo = "bar";
var pc:PendingCall = talkback.returnArray(test);
pc.responder = new RelayResponder(this, 'handleArrayReturn', 'handleFault');
As I mentioned earlier, service calls are asynchronous, which means you won't get the results straight away. What you get instead is a PendingCall. The PendingCall contains a responder which you must fill in with a RelayResponder. The RelayResponder takes three arguments: the first is the scope in which your callbacks are defined (in this case, this, or _root), the second is the result function, and the third is the fault function. So basically to call a remote method you need two lines of code, one for the actual call, and another to define the responders. Not too bad.
This may all seem a bit much but it's really quite a simple (and pointless) application. Take a moment to read over it again and fiddle with the source file to get your bearings before we continue with a more useful and slightly more challenging example.

