Sending Flex Data to PHP using XML

Posted by HCL - RIA Group in


When using Flex you often need to transfer data to a backend server, and one option to do this is to use XML; this tutorial is going to explain the basics of sending XML data to PHP. I am going to show how to build XML data using Flex's built in classes and then we will send the data over to PHP to be handled however you would like. The code for this tutorial is arranged slightly different than earlier tutorial, all the ActionScript code is in separate files that are included into the mxml. This technique is very similar to one used for ASP.Net pages (basically a code behind) - and helps to separate the logic code from the display.

Well what's a tutorial without a working example, so below we have the example application for the day. A simple contact manager which allows you look at the details on each contact and add new contacts. The add contact button at the bottom will pop up a new window to fill out the contact information. Once filled and the "Add Contact" button has been pressed on the pop up, the client XML information is built and send off to PHP. The PHP doesn't do much in this example except parse the XML and build an object from the data. At that point you can do what ever you would like with the data.









Setting up the basic interface

We are going to start by building the interface for the our application. The main screen doesn't have anything particularly complex. We start with a simple panel and inside the panel we add a list for our contacts, several labels and textareas for the different pieces of information available about the contact, and a control bar for an "Add Contact" button. All these come together to create our simple example UI. All this is in the code below.





<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"


layout="absolute" width="432" height="331"

viewSourceURL=

"/files/Tutorials/Flex/XMLAddress/srcview/index.html">



<mx:Panel width="100%" height="100%" layout="absolute"

title="PHP and XML Address Book">



<mx:Label x="5" y="2" text="Contacts" fontSize="13"/>


<mx:List id="contactList"

height="216" width="162" y="25" x="5"/>



<mx:Label x="175" y="2" text="Contact Details"

fontSize="13"/>



<mx:Label x="175" y="28" text="Name:"/>

<mx:Label x="237" y="28" id="contactName"/>


<mx:Label x="175" y="54" text="Phone:"/>

<mx:Label x="237" y="54" id="contactPhone"/>


<mx:Label x="175" y="80" text="Address:"/>

<mx:TextArea x="237" y="79" id="contactAddress" height="59"


editable="false" wordWrap="true" borderStyle="none"/>


<mx:Label x="175" y="146" text="Notes:"/>


<mx:TextArea x="237" y="146" id="contactNotes" height="95"


borderStyle="none" editable="false" wordWrap="true"/>


<mx:ControlBar horizontalAlign="right">


<mx:Button label="Add Contact"/>

</mx:ControlBar>

</mx:Panel>

</mx:Application>





You might notice that I have included the view source link, which is using the nice view source code. This will allow you to look around at all the source and also the PHP code used in the example.

Creating main application ActionScript

Next we are going to start building the actionscript behind the main mxml file. The first thing we do is create a new actionscript file, mine is named "XMLAddressBookTutorialScript.as" because my main mxml file happens to be "XMLAddressBookTutorial.mxml". I follow the same pattern for all my files.

The first item to be added to the script file is a couple variables that we are going to use. The first is an XMLListCollection, which we use to hold all of our contacts and the second is a single XML item for the currently selected contact from our list. Another item we are going to build here is a initialization function for the application. This function sets a couple static parameters on the XML object (more on this in a second) - I also setup the initial names in the list here but that code is unimportant.

import flash.events.Event;

import mx.collections.XMLListCollection;
import mx.managers.PopUpManager;

[Bindable]
private var contacts:XMLListCollection;
[Bindable]
private var selectedContact:XML;

private var addContactPopUp:AddContactForm;

private function initApp():void
{
XML.ignoreWhitespace = true;
XML.prettyPrinting = false;
contacts = new XMLListCollection();
}

The two properties that I set on the XML class are above. The first, ignoreWhitespace, will ignore space characters at the beginning or end of any text nodes. The second is prettyPrinting which is much more important because it will make sure that when we use toXMLString() that the XML is simply printed without any added formatting (that would screw up parsing it in PHP). Now we need to add our script file to our mxml file and also hook up the initialization function.

We first add a tag to our application, directly under the opening application tag. Inside this tag we set a property named source equal to the path to our script file, which should be in the same directory. Also done at this time is the hooking into the creation complete event of the main application tag. Both snippets can be found below.

xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="432" height="331"
creationComplete="initApp()"
viewSourceURL=
"/files/Tutorials/Flex/XMLAddress/srcview/index.html">

The new script tag.

source="XMLAddressBookTutorialScript.as" />

With that done we can now start building new contacts. The next item of business is to hook up the Add Contact button at the bottom of our panel. This is done by simply adding a click event to the button. The function is then added to our script file. The following code is our new button.

label="Add Contact" click="addContact()" />

Inside the actionscript file we add the addContact function which does a couple things. But before we get too far we add a new private variable named addContactPopUp. This variable will hold an AddContactForm, which we will get to building in just a moment. Back to the addContact function - inside this function we popup a new window and then center it. For more information about building and using pop ups check out our pop up menus tutorial. The new function which is added to our actionscript file follows:

import mx.managers.PopUpManager;

private var addContactPopUp:AddContactForm;

private function addContact():void
{
addContactPopUp = AddContactForm(
PopUpManager.createPopUp(this, AddContactForm)
);

PopUpManager.centerPopUp(addContactPopUp);
}

Building the Add Contact pop up window

So now we are going to switch gears a little bit and build a quick pop up window. For the pop up I built a class that extended TitleWindow. The mxml file, "AddContactForm.mxml" for this window doesn't have a lot to it - just a couple labels and text inputs to enter the contact information. Again we have a control bar with a button for adding the contact.

xml version="1.0" encoding="utf-8"?>
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="390" height="262"
title="Add Contact" showCloseButton="true"
close="{PopUpManager.removePopUp(this)}">


[Event(name="contactAddEvent", type="flash.events.Event")]

source="AddContactFormScript.as" />
x="10" y="0" text="Name:"/>
x="194" y="0" text="Phone:"/>
x="10" y="16" id="addName" width="165"/>
x="195" y="16" id="addPhone" width="165"/>
x="10" y="46" text="Address:"/>
x="10" y="64" width="165" height="110"
id="addAddress"/>

x="195" y="46" text="Notes:"/>
x="195" y="64" width="165" height="110"
id="addNotes"/>

horizontalAlign="right">
label="Add Contact" click="addContact()" />


A few items to note are the Event metatag which is added to the metadata. This defines a custom event for this class of type flash.events.Event, more on Event metatag can be found here. When the close button is pressed we remove the pop up using PopUpManager Also you can see we included an actionscript source file "AddContactFormScript.as" and finally we have a click event for our button.

We now create the actionscript file we have included into the mxml file. Inside this file is almost nothing; all we do is dispatch the custom event we created when the add contact button is clicked.

import flash.events.Event;

import mx.managers.PopUpManager;

private function addContact():void
{
dispatchEvent(new Event("contactAddEvent"));
}

Producing the contact XML object

In our pop up window we throw an event when the user clicks the add contact button. Well, we are going to add an event listener for this custom event. We attach the event listener when we create the pop up, so in our main script file we are going to add the following to our addContact function.

addContactPopUp.addEventListener(
"contactAddEvent",
addContactToList
);

Next we need to create the function that is defined in the addEventListener call. This function is going to do most of the heavy lifting for the application. So I will show it off real quick then go through the pieces.

private function addContactToList(event:Event):void
{
//Initalizing using string
var newContact:XML = new XML("");
//Setting attributes using .@
newContact.@name = addContactPopUp.addName.text;
newContact.@phone = addContactPopUp.addPhone.text;

//Adding child node using .appendChild
var address:XML =
{addContactPopUp.addAddress.text}
;
newContact = newContact.appendChild(address);

//And using . to set child node
newContact.notes = addContactPopUp.addNotes.text;
contacts.addItem(newContact);
PopUpManager.removePopUp(addContactPopUp);
}

The function is started by creating a new XML object for our new contact. We initialize the XML to be a simple XML structure of:

<contact></contact>

Once that is in place we can start adding attributes and child nodes using E4X XML processing standard, more info here. We first add two attributes to our XML root node using .@ syntax; this allows us to just use .@name to reference the "name" attribute. Then we can simply set the attributes to the value we want. There are also functions to handle setting attributes.

To add the address and notes we append a child node to the our new contact XML. We first do this by creating an XML object for the address and setting it equal to a simple xml structure holding the address in the text of a
node. This is then appended as a child to our new contact XML. The second method we use is much easier and take advantage of E4X processing; this time we can just use . (dot) syntax to access and set child nodes. That pretty much takes care of creating the XML.

Last we add it to our contact list and also remove the pop up window.

Displaying the XML data

We use the same E4X syntax to display the data by doing some nice data binding to our visual components and the list. The first item to bind is our contact list variable which we created earlier in the tutorial. We bind this to our list component's dataProvider property. Also we want to keep a current reference to the selected contact in the list which can be done by using a tag. The updated list and new tag are below.

id="contactList"
height="216" width="162" y="25" x="5"
dataProvider="{contacts}"/>

The new tag.

source="contactList.selectedItem as XML"
destination="selectedContact" />

To display the correct information in our list though we need use a label function, which is also added to our list component. This label function takes in the row data and returns the string to be displayed; in our case we are just going to return the value of the name attribute. This gives us our final list component and a new function to go in our main script file.

id="contactList"
height="216" width="162" y="25" x="5"
dataProvider="{contacts}" labelFunction="showName"/>

New function for the script file:

private function showName(data:Object):String
{
return data.@name;
}

Now that we have a reference to the currently selected contact we can update the labels and textareas to bind their text to values in the current contact. In our panel we update the labels to reflect the data binding. The new items are below.

x="237" y="28" id="contactName"
text="{selectedContact.@name}"/>

x="237" y="54" id="contactPhone"
text="{selectedContact.@phone}"/>

x="237" y="79" id="contactAddress" height="59"
editable="false" wordWrap="true" borderStyle="none"
text="{selectedContact.address}"/>

x="237" y="146" id="contactNotes" height="95"
borderStyle="none" editable="false" wordWrap="true"
text="{selectedContact.notes}"/>

Sending XML data to PHP

The final thing we need to do in Flex is send our XML data to PHP to be handled. We are going to do this using a simple HTTPService which will send our XML data as a GET variable to a PHP script to parse and handle the data. We define the http service just under our script tag in the main mxml file like so:

id="bookParser"
url=
"/files/Tutorials/Flex/XMLAddress/php/AddressBookParser.php"
method="GET" resultFormat="text" />

Sending it is just as easy, we do this by simply adding a tiny bit of code to the end of our function to build the XML object. This code just creates a parameter object and sets the property contact equal to the return of our new contact object calling toXMLString. The following code is added to the end of the addContactToList function.

var params:Object = new Object();
params.contact = newContact.toXMLString();
bookParser.send(params);

Parsing XML in PHP

Now that data has been sent to PHP we still need to parse it and then it can be handled. Below is the entirety of PHP file I used. You first will see a small class to hold details about a contact, and the rest is there to parse the XML data (we will go over this in just a second).


class Contact
{
public $name;
public $phone;
public $address;
public $notes;
}

$contacts = array();

$xml = new XMLReader();
$xml->XML(stripslashes($_GET["contact"]));
$xml->setParserProperty(XMLReader::VALIDATE, false);
$xml->setParserProperty(XMLReader::LOADDTD, false);

while($xml->read())
{
if($xml->nodeType == XMLReader::ELEMENT)
{
switch($xml->name)
{
case("contact"):
$contact = new Contact();
$contact->name = $xml->getAttribute("name");
$contact->phone = $xml->getAttribute("phone");

$xml->read(); // read start of address
$xml->read(); // read text of address
$contact->address = $xml->value;
$xml->read(); // read end of address

$xml->read(); // read start of notes
$xml->read(); // read text of address
$contact->notes = $xml->value;
array_push($contacts, $contact);
break;
}
}
}

foreach($contacts as $c)
{
print_r($c);
}
?>

Well the first thing we do is create an XMLReader object (only available in php 5+). This is used to parse the xml easily. We also set a couple parse properties on the XMLReader object. These tell the XMLReader to ignore trying to validate the XML or apply a DTD to it.

We then loop through the XML document reading each node; while doing this we check to see if it is an opening node, and if it is one we then switch on the name (yes we don't need to do this in this particular case but I was making it more general). If the name is "contact" we know we have a new contact to add. We then build a new contact object by getting the attributes. Once the attributes are gotten we then read to get to the address text node (there might be a better way to do this depending on your situation) and the final notes text node. Once the contact information is added to the contact object we add it to an array of contacts.

Just to double check things I printed out the contents of my array, which would only have one contact for this application. I used FireBug - which I highly recommend - to make sure I get the correct response from PHP.

Wrapping up

That pretty much takes care of the basics of handling XML in Flex and sending it over to PHP to be handled. I am not including all the source in one big box because, well, there is a lot of it, but you can browse the source here. If you interested in some other PHP/Flex stuff we have several other tutorials and the Adobe Dev Center has some like this one. If I was unclear about anything let me know or if you just want to leave a comment go for it.

This entry was posted on Jul 16, 2008 at 6:32 PM and is filed under . You can follow any responses to this entry through the comments feed .

0 comments

Post a Comment