Adobe Flex is cool and all, but why settle for one framework when you can make it more powerful with a second? Recently I developed an application which was using all PHP on the backend, and all Javascript on the frontend. I developed the PHP interface so that all interactions from the frontend occurred via AJAX calls to a gateway class which was just a list of entry functions that would in turn call library functions and then echo out a JSON encoded result.
Since all of the frontend functionality was focused on the gateway, and nothing past that, I figured I could really test this library by developing a second frontend with a second gateway. Within about 2 hours I had a working frontend for the application running on Adobe AIR using AMFPHP as an interface for remoting calls to the PHP backend. Here’s a run down of how I set this up.
You can grab AMFPHP from the developer’s homepage. AMF is a binary serialization format for Action Script objects to all messages to be sent to server-side services, and AMFPHP is just a PHP implementation of that format.
Installation is quick and easy, just drop the amfphp/ root folder into the htdocs directory of your web server. To test out the installation, go to http://localhost/amfphp/browser/. If all goes well, you should be presented with a Flex application.
For the PHP code, we can keep it simple. Create a file with a matching classname. I named my class AirDemo and saved it as AirDemo.php:
class AirDemo {
public function helloWorld( $a_name )
{
return "Hello, " . $a_name;
}
}
Now stick that PHP file into a folder, let’s call it airdemo_library, and then stick the folder in the amfphp/services directory. Restart the amfphp/browser/ application and you’ll now see airdemo_library in the left hand tree. Expanding that will give you the AirDemo class, and then you will be able to test out communication by sending requests manually.
Setting up the Flex side is a little more involved. First, create a services-config.xml file under your src/ directory:
<services-config>
<services>
<service id="amfphp-flashremoting-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="amfphp">
<channels>
<channel ref="my-amfphp"/>
</channels>
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://localhost/amfphp/gateway.php" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
The only thing to pay attention to here is the endpoint uri argument needs to point to your AMFPHP installation. This essentially tells Flex where to find the remoting gateway. We then tell Eclipse to look for this remoting gateway by adding a line to the Flex compiler options:

Now we’ve got Eclipse configured to compile your Flex/AIR application so that it’s aware of AMFPHP, all that’s left is to actually use it. This is the easiest part. I’ve created a simple application that provides a text box and a button, and when you click the button it calls the helloWorld( ) function that I’ve already declared on the PHP backend. So the user will type in a name, click the button, and get a message back from the server.
To hook up the remoting methods, add this to the top of your MXML document:
<mx:RemoteObject id="airdemo_service" fault="faultHandler( event )" showBusyCursor="true" source="airdemo.AirDemo" destination="amfphp">
<mx:method name="helloWorld" result="resultHandler( event )" />
</mx:RemoteObject>
The RemoteObject id is whatever you’d like to refer to your remote library as within your ActionScript, and the source is the library.class you are defining remote methods for. Each mx:Method you declare uses a literal string to identify a remote function, as well as a local ActionScript function that will handle the result. To call the function, just call it like you would any ActionScript function:
airdemo_service.helloWorld( txtName.text );
And that’s that. Here’s a screenshot of the end result:
