jump to navigation

Flex & PHP Tutorial – Transmitting data using JSON August 28, 2010

Posted by Tournas Dimitrios in Flex.
trackback

Basically what I am going to go over here is how to use php and json to send data to your flex application, and then how to use that data in Flex.
This is actually a lot easier than it seems because PHP and Flex both have functions to handle json data transmissions. For Flex, the one thing you need to make sure is that you have the corelib from Adobe in order to use the JSON functions – this can be found at Adobe Flex coreLib. This can be added to a project in Flex builder by going into the properties of a project then to “Flex Build Path” and adding the .swc to the library path. For PHP, if you have a version greater than 5.2, you are all set. If not, you can either upgrade, or install the php-json extension.

The final product of what we are going to create today is a very simple little app, and not particularly useful, but it does have everything needed to show how to communicate between php and flex using json.The first thing we are going to go over is the php code. The php code creates a few classes for the objects that we will pass to our flex application. We also have code to check if a GET variable has been set, we use this to tell the php code what we are requesting. If the variable “getPerson” is set we create a person and echo it (after we encode it into json) to send it to the Flex app. Ideally your data would be stored in a database, but for simplicity, we’re just creating Person objects directly in the php code.


class Person
{
  public $first_name;
  public $last_name;
  public $email;
  public $address;
}

class Manager extends Person
{
  public $title;
  public $employees;
}

if(isset($_GET['getPerson']))
{
  $p = new Person();
  $p->first_name = 'Chuck';
  $p->last_name = 'Killer';
  $p->email = 'fake@email.com';
  $p->address = '5555 Some Street City, State 52423';
  echo json_encode($p);
}

if(isset($_GET['getManager']))
{
  $p1 = new Person();
  $p1->first_name = 'Joe';
  $p1->last_name = 'Schmoe';
  $p1->email = 'joe.schmoe@email.com';
  $p1->address = '5424 Some Street City, State 12314';
  $p2 = new Person();
  $p2->first_name = 'Bob';
  $p2->last_name = 'Hacker';
  $p2->email = 'bob.hacker@email.com';
  $p2->address = '1414 Some Street City, State 12412';
  $p3 = new Person();
  $p3->first_name = 'Kevin';
  $p3->last_name = 'Putvin';
  $p3->email = 'kevin.putvin@email.com';
  $p3->address = '6123 Some Street City, State 41241';
  $m = new Manager();
  $m->first_name = 'Manager';
  $m->last_name = 'Dude';
  $m->email = 'manager.dude@email.com';
  $m->address = '5534 Some Other Street City, State 91230';
  $m->title = 'Office Manager';
  $m->employees = array($p1, $p2, $p3);
  echo json_encode($m);
}

?>

The next thing to do is setup the basic application for flex. The following code is the simplest flex application. This sets up an application with specified height and width and also adds the view source option to the movie, with the source file specified by “viewSourceURL”.

< ? x ml version="1.0" encoding="utf-8"?>
<m x: A pplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   width="500" height="410" viewSourceURL="../files/JSONTutorial.mxml">
pplication>

The next thing to do is setup the user interface. This is pretty standard flex mxml, nothing should look out of place. The user interface has a couple of text fields for the data we get back from the php code, a datagrid, and two buttons. This is all setup on a panel. The one important thing to observe is that the dataField properties on the DataGridColumns, these names correspond to the variables from the objects in the php code.This code goes inside the Application block.

<m x: P anel x="0" y="0" width="500" height="410" layout="absolute"
   title="Simple JSON Example">
  <m x: D ataGrid x="10" y="174" width="460" enabled="true" editable="false"
     id="dgEmployees">
    <m x: columns>
      <m x: D ataGridColumn headerText="First Name" dataField="first_name"/>
      <m x: D ataGridColumn headerText="Last Name" dataField="last_name"/>
      <m x: D ataGridColumn headerText="Email" dataField="email"/>
      <mx : D ataGridColumn headerText="Address" dataField="address"/>
    </m x: columns>
  </m x: D ataGrid>
  <m x: B utton x="116" y="338" label="Get Employee" id="getPerson" />
  <m x: B utton x="266" y="338" label="Get Manager" id="getManager" />
  <m x: L abel x="131" y="12" text="Name"/>
  <m x: T extInput x="189" y="10" id="txtName" editable="false"/>
  <m x: L abel x="131" y="42" text="E-mail"/>
  <m x: T extInput x="189" y="40" id="txtEmail" editable="false"/>
  <m x: L abel x="131" y="68" text="Address"/>
  <m x: T extInput x="189" y="66" id="txtAddress" editable="false"/>
  <m x: L abel x="131" y="94" text="Title"/>
  <m x: T extInput x="189" y="92" id="txtTitle" editable="false"/>
  <m x: L abel x="131" y="122" text="Has Employees"/>
  <m x: T extInput x="229" y="120" width="120" editable="false"
     id="txtEmployees" text="No"/>
  <m x: L abel x="10" y="148" text="Employees:"/>
</m x: P anel>

Now that our user interface is setup and ready to go we can add our http services to go ask for the data from our php code. Now in flex you can setup all kinds of different services. We are just going to setup a simple http request service that sets a GET variable and tells the service that we want to run a function once we get the results. As you can see in the code below we send both services out to the same php page, which is the one we made earlier. Also each one sets one GET variable, which is done inside the mx:request block. Lastly, the result is an event which we hook to, to process the results of the request (our JSON data). This code goes at the very beginning of the file right after the Application opening element.

<m x: H TTPService id="personRequest" url="../files/json_tutorial.php" useProxy="false"
   method="GET" resultFormat="text" result="personJSON(event)">
  <mx:request xmlns="">
    <getPerson>"true"</getPerson>
  </m x: request>
</m x: H TTPService>
<m x: H TTPService id="managerRequest" url="../files/json_tutorial.php" useProxy="false"
   method="GET" resultFormat="text" result="managerJSON(event)">
  <m x: request xmlns="">
    <getManager>"true"</getManager>
  </m x: request>
</m x: H TTPService>

Ok, now let’s get into the actual JSON decoding, which is really simple. So at this point if your using flex builder you will be getting a error message about an undefined method for personJSON(event) and managerJSON(event). We are going to solve that right now. First things first – lets just put in the method signatures so the application can build and run. The way this is done is by inputting a script tag and adding our actionscript functions inside there. You’ll notice we added two import statements to import our JSON serialization functions and use the result event. This code will go right above the http services we just setup and below the Application opening element.

<m x: S cript>
 <![CDATA[
   import mx.rpc.events.ResultEvent;
   import com.adobe.serialization.json.JSON;

   private function personJSON(event:ResultEvent):void
   {
   }

   private function managerJSON(event:ResultEvent):void
   {
   }
 ]]>
</m x: S cript>

Now down to the actual work of our application, the first thing we need to do in both of the functions is get the result back and we store it in a string. The next thing we do is call the function JSON.decode on the string, this function will return us an object with all the same properties of the one sent by php – we set this equal to a variable. We can now use this object and reference the properties using the . (dot) notation. So to get the first name of the person we simply use variable.first_name and so on for the rest of the variables. So that takes care of getting a person. And the above code is changed like so.

<m x: Script>
 <!--[<span class="hiddenSpellError" pre="">CDATA</span>[-->
   import mx.rpc.events.ResultEvent;
   import com.adobe.serialization.json.JSON;

   private function personJSON(event:ResultEvent):void
   {
     //get the raw JSON data and cast to String
     var rawData:String = String(event.result);
     var person = JSON.decode(rawData);
     txtName.text = person.first_name + " " + person.last_name;
     txtEmail.text = person.email;
     txtAddress.text = person.address;
     txtEmployees.text = "No";
     txtTitle.text = "No Title";
   }

   private function managerJSON(event:ResultEvent):void
   {
     //get the raw JSON data and cast to String
     var rawData:String = String(event.result);
     var manager = JSON.decode(rawData);
     txtName.text = manager.first_name + " " + manager.last_name;
     txtEmail.text = manager.email;
     txtAddress.text = manager.address;
     txtEmployees.text = "Yes";
     txtTitle.text = manager.title;
   }
 ]]>
</m x: S cript>

This takes care of all the text boxes we created and puts the correct values in them. Now we have to worry about that datagrid we created, and you might have noticed we haven’t dealt with the employees of the manager yet. Well this is handled pretty nicely in the manager function. We are going add a new var called employees and this will be an Array. Because of the JSON.decode function we can simply cast the employees as an Array and all will be fine. The next thing we do is actually create an ArrayCollection to use for the data provider for the datagrid. This is a best practice when using array data for the provider because the ArrayCollection allows for some extra functionality. The final setup is to set the dataGrid.dataProvider equal to the ArrayCollection. Also we set the dataProvider equal to null in the person function to clear our the data in the data grid. To make all this work we also need to add another import for ArrayCollection. This leaves us with the following code.

<m x: S cript>
 <!--[<span class="hiddenSpellError" pre="">CDATA</span>[-->
   import mx.collections.ArrayCollection;
   import mx.rpc.events.ResultEvent;
   import com.adobe.serialization.json.JSON;

   private function personJSON(event:ResultEvent):void
   {
     //get the raw JSON data and cast to String
     var rawData:String = String(event.result);
     var person = JSON.decode(rawData);
     txtName.text = person.first_name + " " + person.last_name;
     txtEmail.text = person.email;
     txtAddress.text = person.address;
     txtEmployees.text = "No";
     txtTitle.text = "No Title";

     //Data Grid Code
     dgEmployees.dataProvider = null;
   }

   private function managerJSON(event:ResultEvent):void
   {
     //get the raw JSON data and cast to String
     var rawData:String = String(event.result);
     var manager = JSON.decode(rawData);
     txtName.text = manager.first_name + " " + manager.last_name;
     txtEmail.text = manager.email;
     txtAddress.text = manager.address;
     txtEmployees.text = "Yes";
     txtTitle.text = manager.title;

     //Data Grid Code
     var employees:Array = manager.employees as Array;
     var employeesCollection:ArrayCollection = new ArrayCollection(employees);
     dgEmployees.dataProvider = employeesCollection;
   }
 ]]>
</m x: S cript>

Now you might have tried it at this point and said “Hey, this isn’t working!”, well that is true. This is because we never hooked our buttons up to send the requests. This is really simple, we just add click events for both buttons and the corresponding service.send() commands to the click events. The code below is our new button code.

< m x: B utton x="116" y="338" label="Get Employee" id="getPerson"
   click="personRequest.send();"/>
utton x="266" y="338" label="Get Manager" id="getManager"
   click="managerRequest.send();"/>

So this leaves us with the final flex code. This along with the php code at the beginning of the tutorial allows for JSON data to be sent to your flex applications.

< ? x ml version="1.0" encoding="utf-8"?>
< m x: A pplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   width="500" height="410" viewSourceURL="../files/JSONTutorial.mxml">
  <m x: S cript>
   <!--[<span class="hiddenSpellError" pre="">CDATA</span>[-->
     import mx.collections.ArrayCollection;
     import mx.rpc.events.ResultEvent;
     import com.adobe.serialization.json.JSON;

     private function personJSON(event:ResultEvent):void
     {
       //get the raw JSON data and cast to String
       var rawData:String = String(event.result);
       var person = JSON.decode(rawData);
       txtName.text = person.first_name + " " + person.last_name;
       txtEmail.text = person.email;
       txtAddress.text = person.address;
       txtEmployees.text = "No";
       txtTitle.text = "No Title";

       //Data Grid Code
       dgEmployees.dataProvider = null;
     }

     private function managerJSON(event:ResultEvent):void
     {
       //get the raw JSON data and cast to String
       var rawData:String = String(event.result);
       var manager = JSON.decode(rawData);
       txtName.text = manager.first_name + " " + manager.last_name;
       txtEmail.text = manager.email;
       txtAddress.text = manager.address;
       txtEmployees.text = "Yes";
       txtTitle.text = manager.title;

       //Data Grid Code
       var employees:Array = manager.employees as Array;
       var employeesCollection:ArrayCollection = new ArrayCollection(employees);
       dgEmployees.dataProvider = employeesCollection;
     }
   ]]>
 </m x: Script>
< m x: H TTPService id="personRequest" url="../files/json_tutorial.php"
     useProxy="false" method="GET" resultFormat="text" result="personJSON(event)">
    <m x: request xmlns="">
      <getPerson>"true"</getPerson>
    </m x: request>
  </m x: HTTPService>
  <m x: HTTPService id="managerRequest" url="../files/json_tutorial.php"
     useProxy="false" method="GET" resultFormat="text" result="managerJSON(event)">
    <m x: request xmlns="">
      <getManager>"true"</getManager>
    </m x: request>
  </m x: HTTPService>
  <m x: Panel x="0" y="0" width="500" height="410"
     layout="absolute" title="Simple JSON Example">
    <m x: DataGrid x="10" y="174" width="460" enabled="true"
       editable="false" id="dgEmployees">
      <m x: columns>
      < m x:  D ataGridColumn headerText="First Name" dataField="first_name"/>
       < m x: D ataGridColumn headerText="Last Name" dataField="last_name"/>
        < m x: D ataGridColumn headerText="Email" dataField="email"/>
       < m x: D ataGridColumn headerText="Address" dataField="address"/>
      </m x: columns>
    </m x: DataGrid>
    <m x: Button x="116" y="338" label="Get Employee" id="getPerson"
       click="personRequest.send();"/>
    <m x: Button x="266" y="338" label="Get Manager" id="getManager"
       click="managerRequest.send();"/>
    < m x: L abel x="131" y="12" text="Name"/>
   < m x: T extInput x="189" y="10" id="txtName" editable="false"/>
    < m x: L abel x="131" y="42" text="E-mail"/>
   < m x: T extInput x="189" y="40" id="txtEmail" editable="false"/>
   < m x: L abel x="131" y="68" text="Address"/>
   < m x: T extInput x="189" y="66" id="txtAddress" editable="false"/>
   < m x: L abel x="131" y="94" text="Title"/>
    < m x: T extInput x="189" y="92" id="txtTitle" editable="false"/>
    <m x: Label x="131" y="122" text="Has Employees"/>
  < m x: T extInput x="229" y="120" width="120" editable="false"
       id="txtEmployees" text="No"/>
   < m x: L abel x="10" y="148" text="Employees:"/>
  </mx:Panel>
</m x: A pplication>
Advertisements

Comments»

No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s