Greg's Blog

helping me remember what I figure out

Flash Remoting With PHP

| Comments

Not so long ago I made my first foray into invoking a CFC from Flash MX and shortly after that I stumbled across a PHP port of Flash remoting. I immediately decided to have a play round with it as I don?t have access to ColdFusion MX on this server and as I indicated back then the idea of working with Flash and dynamic content was something that really appealed to me. So here was the opportunity to build something Flash based and also put it to good practise. In the following I shall go through the set up, the PHP class that will be invoked by the Flash movie and highlight the differences between the CF version and the PHP one.

Remoting services with PHP

First off head on over to http://www.amfphp.org/ and grab the latest install files. Now the directory structure is rather important as the PHP files and classes reference one another quite a bit. The easiest approach to follow is to either install the files just off the root of your web site or create a mapping that will have the same effect. Hence on my local configuration I extracted the files into my Apache/htdocs directory. After you have done this you should see a flashservices folder under your web site root. Ok so far so good.

Now we will be following a similar example to the CF one whereby we?ll be using a form to submit a value to a PHP class, which will concatenate the value with a string, which will return: ?Hello your submitted string?. So we?ll be creating a class called SubmitForm, as a result create a directory called submitform also in your root, or alternatively place it wherever you like just make sure you create a virtual mapping for it.

Root
|—–flashservices
|—–submitform

The above representation shows what your directory structure should ideally look like. In the last folder we added, create another one called: services. This is the actual folder that will hold your class file: submitForm.php. Back up one level create a file called gateway.php. The latter file will hold the following PHP code:

<?php
include “../flashservices/app/Gateway.php”;
$gateway = new Gateway();
$gateway -> setBaseClassPath(“./services/”);
$gateway -> service()
?>

This file includes all the relevant flash remoting components that you will need while setting the path to your services that Flash will interact with.

<?php class SubmitForm {

function SubmitForm() {
$this->methodTable = array(
“submitThis” => array(
“description” => “Echoes the passed argument back to Flash (no need to set the return type)”,
“access” => “remote”, // available values are private, public, remote
“roles” => “role, list”, // currently inactive
“arguments” => array(“arg1”)
)
);
}
function submitThis($nameField) {
$thisResult = “Hello “.$nameField;
return $thisResult;
}
}
?>

The above code is the actual contents of you class file, here you define the class a constructor and a method called: submitThis. This latter method is the one that will eventually be called by the Flash movie, passing the submitted form value to it. Nothing amazingly complicated happens here. The constructor (SubmitForm()) sets an array that will be returned back to the Flash movie for the submitThis method. At this point you might as well create another file in the submitform folder and this one will be used for your flash movie as it is embedded into an HTML template.

And that pretty much covers the server side of the set up. Now I encountered a few problems with the class file, my constructor I named in-correctly and also I made use of the following code to set the return variable:

$this->thisResult = ?Hello ?.$nameField;

However this did not work and resulted in null values being passed back to Flash, so follow the code above.

The Flash form

The form itself has changed very little from the example I built using ColdFusion as the backend, so let?s just take a closer look at the ActionScript:

// Include the Required NetService class files
#include “NetDebug.as”
#include “NetServices.as”
#include “DataGlue.as”
var gatewayurl = “http://localhost/submitform/gateway.php”;
function onClick(btn)
{
trace(“onClick ” + btn._name);
getSubmittedData();
gotoAndStop(“response”);
}

// get the data from the ui elements on page 1
function getSubmittedData()
{
trace(nameField.text);
userData.nameField = nameField.text;
trace (“The value of the submitted field is:” + userData.nameField);
}
function submitDetails()
{
// connect to the Flash Remoting service provider
if (isGatewayOpen == null) {
// do this code only once
isGatewayOpen = true;
// Make the Gateway connection
NetServices.setDefaultGatewayUrl(gatewayurl);
gatewayConnnection = NetServices.createGatewayConnection();
submitForm = gatewayConnnection.getService(“submitForm”, this);
trace(“Connected”);
// CALL Web service: submit the form variable
submitForm.submitThis(userData.nameField);
trace(“sent request”);
}
}

// :::: DEFAULT RESPONDERS ::::
function submitThis_Result(result)
{
trace(“server responded: The result is ” + result);

trace(“setting the field”);
// This function will be invoked by the server when it has finished processing
myResult.text = “The Php class replied with: ” + result;
}

function initData()
{
// make sure we only call initData once
if ( inited )
return;
inited = true;

// modeling the form choices with data

// set initial values
userData = new Object();
userData.nameField =”“;
trace (“object created and populated”);
}

The first thing worth noting is that here I have included the ActionScript remoting components by default, rather than after the form has been submitted. Additionally I have declared a variable [var gatewayurl = “http://localhost/submitform/gateway.php”;] that stores the path to our gateway.php file which if you remember points to the PHP flash services files.

Now let?s take a quick look at the submitDetails() method, which submits our details to the PHP class. Two lines that differ from the CFC are: submitForm = gatewayConnnection.getService(“submitForm”, this); [1] and submitForm.submitThis(userData.nameField);[2].

[1] simply invokes the object, whereas in the CFC version you still had to include the full path in a ?.? Annotation.
[2] in the CFC we simply passed the whole object to the component, whereas in the PHP class case we pass the variable nameField of the object userData.

Subtle differences, but still important. And there you go two implementations on two different platforms with the exact same outcome. One difference however, you can see this one in action here and you can download all the files here.