Adobe Flex with a PHP back-end

You would like to create a great Adobe Flex application which will show data from a MySQL-database. You Googled around and found BlazeDS would be a great back-end solution for retrieving your data. Bad luck, you have no Java experience and/or your hosting provider is not equipped to allow you to deploy BlazeDS at a Tomcat server…

What are your options now? Create the complete back-end solution yourself? Implement a webservice? Simply do some HTTP-posts/gets sending your data as comma separated values? Possible.. but there is another neat solution: ZendAMF. For this PHP-knowledge and a server running the PHP(5) module with ZendAMF is required.

In this article I describe how you can create a simple Flex application which is communicating with the back-end database using ZendAMF.

Install ZendAMF

When ZendAMF is not available yet, and you do have administrator rights at the server, install ZendAMF now.

  1. Download ZendAMF from:
  2. Follow installation instructions in INSTALL.txt which is included in the download.

Create the database

Create a MySQL-database design in data definition language (design.ddl).

DROP TABLE IF EXISTS 'zendamf_example_data';
CREATE TABLE 'zendamf_example_data' (
  'description' VARCHAR(255) DEFAULT NULL,
  'value' INT(11) DEFAULT NULL,
  PRIMARY KEY ('id'),
  UNIQUE KEY 'id' ('id')

Now create this table in the zendamf_example database.

When this database does not exist yet, excecute this command as root user in MySQL:

create database zendamf_example;

From the (bash) prompt, enter this command:

cat design.ddl | mysql -u root -p zendamf_example

Generate a test set

Fill the database with some random data. To accomplish this, we create a stored procedure.

First we remove the stored procedure when it exists already. Next we change the MySQL command delimiter from ; to // Reason for this is that we would like to use ; in the procedure itself. When we don’t change the delimiter, the definition of the stored procedure will stop after the first time we use ;

After defining the stored procedure, we switch the delimiter back to ;

Login into MySQL:

 mysql -u root -p zendamf_example

Execute these commands at the MySQL-prompt:


delimiter //

SET @i = 0;
SET @i = @i + 1;
INSERT INTO zendamf_example_data (value) VALUES (ROUND(RAND()*10));

delimiter ;

The procedure will insert n-rows into the table zendamf_example_data. The ‘id’ is an auto incremented field, so we don’t supply a value. The ‘timestamp’¬† of a row will be updated automatically every time we change the row. ‘Description’ is a text-field which we don’t fill at this moment. The field ‘value’ is filled with a random numeric value in the range 0 to 10.

Now call this procedure to create a test set of 20 records by executing the command:

CALL createTestSet(20);

Tip: To list the stored procedures, execute the command:


Now you can leave MySQL again (quit;)

Setup your development environment

Create a project directory: zendamf_example

Step into this directory (cd zendamf_example)

Create these (sub) directories:

  • server (this directory must be accessible for your HTTP-server)
  • client
  • client/net/videgro/dto

Create the value objects

In this step you create two value objects which will hold the data retrieved from the database. One for the PHP-back-end and one for the Flex-front-end. Later, in the file server/endpoint.php, mapping is performed between these two objects.

PHP Value Object Data (server/VOData.php)

Create a simple PHP-class called VOData with four fields which are not strong typed.

class VOData {
        public $id;
        public $timestamp;
        public $description;
        public $value;

Flex/Actionscript Value Object Data (client/net/videgro/dto/

The actionscript class has strong typing. Casting to these types is done automagicly. The RemoteClass defines the back-end class.

package net.videgro.dto {
     public class VOData {
        public var id:int;
        public var timestamp:String;
        public var description:String;
        public var value:Number;

Create the AMF endpoint (server/endpoint.php)

A small file where a AMF-server is created, a Service-class for this server is configured, a mapping is made between the PHP- and Actionscript- value objects and finally a handle to this server is returned.


$server = new Zend_Amf_Server();

//Mapping the ActionScript VO to the PHP VO
$server->setClassMap("VOData", "VOData");

echo($server -> handle());

Implement the back end-service (server/Service.php)

In this class all magic is done. It consists of two methods which are exposed by the AMF-server. The methods are: getData, which will return all data of the table zendamf_example_data as an array.

The second method is called setData and could be used to set the value of a specific row of the table zendamf_example_data, identified by ‘id’. This method will return a string containing the result of the operation.


define("DATABASE_SERVER", "localhost");
define("DATABASE_USERNAME", "root");
define("DATABASE_PASSWORD", "root");
define("DATABASE_NAME", "zendamf_example");

class Service {

 public function getData() {

        $query = "SELECT * FROM zendamf_example_data";
        $result = mysql_query($query);

        $ret = array();
        while ($row = mysql_fetch_object($result)) {
                $tmp = new VOData();


                $ret[] = $tmp;
        return $ret;

 public function setData($id,$value) {
  $result="Data saved.";


  if ($id!="" && $value!=""){
   $query  = "UPDATE zendamf_example_data SET value='".$value."'";
   $query .= ",description='Set via Flex front-end.'";
   $query .= " WHERE id='".$id."'";
  } else {
   $result="ERROR: Check ID and Value.";
  return $result;

Create a Flex services definition file (client/services-config.xml)

In this file we define a channel for the communication between the Flex front-end and the AMF-server. Ofcourse we also have to specify at which URI the AMF-endpoint could be found.

<?xml version="1.0" encoding="UTF-8"?>
   <service id="amfphp-flashremoting-service"
 <destination id="zend">
   <channel ref="my-zend"/>
 <channel-definition id="my-zend">
  <endpoint uri="http://[URL of your server]/zendamf_example/server/endpoint.php"/>
 <channel-definition id="my-secure-zend">
  <endpoint uri="https://[URL of your server]/zendamf_example/server/endpoint.php"/>

Create Flex-application (client/ZendAmfHelloWorld.mxml)

The complete Adobe Flex application. Main parts of the application are:

  • Declaration of RemoteObject which is pointing to the service defined in services-config.xml
  • Result listeners which handle results (data/faults/messages) returned from the remote service. Respectively update the data array, show an alert box with error or other message.
  • Datagrid and LineChart displaying the data.
  • An input field to update values.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx=""

  import net.videgro.dto.VOData;
  import mx.controls.Alert;
  import mx.collections.ArrayCollection;

  [Bindable] private var _data:Array;

  * Result listener for get data operation
  private function getDataListener(event:ResultEvent):void {
   _data = event.result as Array;

  * Result listener for set data operation
  private function setDataListener(event:ResultEvent):void {
   var result:String = event.result as String;"Result of setting data: "+result);

  * Fault listener for RemoteObject
  private function faultListener(event:FaultEvent):void {, "Error");


  <mx:RemoteObject id="myRemote" destination="zend" source="Service"
        showBusyCursor="true" fault="faultListener(event)">
   <mx:method name="getData" result="getDataListener(event)"/>
   <mx:method name="setData" result="setDataListener(event)"/>

 <mx:VBox top="10" left="10" width="100%" height="100%">
   <s:Label text="1. Click the button: 'Get data'."/>
   <s:Button label="Get data" click="{myRemote.getData()}" />

  <s:Label text="2. Now select a row in the datagrid and enter a new value in the Value-field."/>
  <s:Label text="3. Next click 'Replace value'."/>

   <mx:DataGrid id="myGrid" editable="false" dataProvider="{_data}"

   <mx:Form width="100%">

    <mx:FormItem label="ID">
     <s:TextInput id="idTextInput" enabled="false" width="100"/>

    <mx:FormItem label="Value">
     <s:TextInput id="valueTextInput" restrict="0-9" width="100"/>

    <s:Button label="Replace value"
              click="{myRemote.setData(idTextInput.text,valueTextInput.text)}" />

  <mx:LineChart id="linechart" height="100%" width="70%" showDataTips="true" dataProvider="{_data}">

    <mx:CategoryAxis categoryField="id"/>

    <mx:LineSeries yField="value" form="curve" displayName="Value"/>


  <mx:Legend dataProvider="{linechart}"/>



Build Flex-application

Compile the application using Adobe Flex 4 SDK. Now step into the ‘client’-directory (cd client).

mxmlc  -services "services-config.xml" ZendAmfHelloWorld.mxml

Copy the resulting file: ZendAmfHelloWorld.swf to the directory: ‘server’ (cp ZendAmfHelloWorld.swf ../server/).

Now check the permissions of the four files (endpoint.php Service.php VOData.php ZendAmfHelloWorld.swf) in the directory ‘server’, they must be readable by the webserver daemon.

Test your application

Open the location: http://[URL of your server]/zendamf_example/server/ZendAmfHelloWorld.swf in your favourite browser, for example Mozilla Firefox. In the browser, the Flash-player plugin must be available. To check whether the Flash plugin is available and which version of the plugin is installed, type about:plugins (without http://) in the location bar of Firefox.

Click the ‘Get data’ button to perform a back-end call which will load the data from the database.

Now select a row in the datagrid and type a new value in the Value-field. Next press the button ‘Replace value’. Check the ‘description’-field in the datagrid. It should state at the selected row: ‘Set via Flex front end’ and the new value.

Make communication more secure

To make the communication between front- and back-end more secure, use a HTTPS/SSL server instead of plain unencrypted HTTP.

Open the file services-config.xml in the client-directory. Find the line: <channel ref=”my-zend”/> and replace it with <channel ref=”my-secure-zend”/> Also remove the channel-definition¬† for ‘my-zend’.

Check the endpoint URI of the channel definition for my-secure-zend. It must be starting with https and not http.

Now recompile ZendAmfHelloWorld and put it again in the ‘server’-directory.

Access ZendAmfHelloWorld.swf by typing the address https://[URL of your server]/zendamf_example/server/ZendAmfHelloWorld.swf in your browser. So httpS instead of http. Ofcourse you need to setup a HTTPS-server before you try this. Sadly the configuration of a HTTP-server is out of scope of this article.

Read more