Whenever you want to do remoting, you need a server-side library that will handle that part of communication. For PHP backends you have a choice of four libraries: Zend AMF (the latest on this stage), AMFPHP, WebORB for PHP, and SabreAMF. I’ve already written articles on two of them, AMFPHP and ZendAMF. In this post I will focus on WebORB. Next, I will play with SabreAMF, and I will finish this series with an article comparing them.
You can download a Flex Builder project that contains the code for this article from here. Inside of the archive you will find a readme.txt file explaining what to do with it.
Installing WebORB for PHP
After downloading WebORB for PHP (you need to register first), just extract the files somewhere on your computer. Next create a folder called weborb inside of your PHP web server, and then copy the content of the archive you’ve just extracted into it. You should end up with a folder that have a bunch of folders and files (see the Figure 1).
Figure 1. Folder structure of WebORB for PHP.
WebORB comes with a lot of examples, and it also comes with a console that let’s you do a lot of things, including learning the basics of WebORB, seeing the available services exposed by WebORB, accessing the many Flex sample applications that came with WebORB (see Figure 2). You can find much more more information on this page.
Figure 2. WebORB console.
What is AMF and remoting and why should you use it?
If you already know these answers, you may want to skip to the next section. Let’s start by understanding remote procedure calls. Remote procedure calls let Flex applications make direct calls on the methods of your server side classes. Using BlazeDS or LiveCycle Data Services you can expose your Java and ColdFusion classes to the Flex application. However, if you use PHP you need a third party library on the server to expose PHP classes directly. Existing solutions include Zend AMF, WebORB, and AMFPHP. AMF is a binary protocol for serializing the messages. Because it is binary, it is more efficient in terms of bandwidth and server processing load than JSON or XML methods. If you want to see for yourself how much more efficient it is, James Ward has put together a nice benchmark.
WebORB is a PHP library that knows how to serialize and deserialize the AMF protocol, and thus lets you expose PHP classes to Flex applications. Another compelling reason for using remoting is code reuse. Because you can call methods on PHP classes and these methods can return PHP objects, you don’t have to modify your existing code to output JSON or XML.
As I noted earlier, WebORB remoting uses AMF to serialize messages between the server and Flex client. It also offers the ability to map an ActionScript class to a PHP class. For example, suppose you want to display in Flex the information from a table with the following structure:
When using remoting, you create an ActionScript class to model this data in the client and a PHP class to model the same data on the server. When you create the PHP class that you want to call from Flex, you add a method that, for example, retrieves all the contacts from the table. This method will return an array of PHP VO classes, and in Flex you will get an array of ActionScript objects. All the conversions from PHP objects to AMF to ActionScript objects are done automatically for you by Flex and WebORB.
When you use XML or JSON for remoting, you’ll typically need extra steps in Flex to process the data in order to display or store it.
Let’s look at a working example.
Create the Flex PHP project
Usually, when I work with Flex and PHP projects, I prefer to use Flex Builder and Zend Studio installed together. It is possible, however, to work with Flex Builder and a PHP plugin to help you with the PHP code. Either way, you should create a Flex project that uses PHP on the server side (if you plan to use Zend Studio and Flex Builder, first create a Zend PHP Project, then use the Add Flex Nature wizard to add Flex PHP nature on the project). This way you streamline the deployment of the SWF file (the compiled result of the Flex project) to the PHP server. I chose to create a new project called “flex_weborb”.
Choose New > Folder, and then click on the Advanced button, and select the option Link to folder in the file system. Next, click the Browse button and chose the weborb folder you created earlier (the folder that holds the content of the WebORB archive).
Create the PHP code
All the PHP classes you want to expose to the Flex client need to be inside of the folder weborb/Services. If you navigate to this folder, you will find a bunch of files already in there. These are the services used by the samples that come with the framework. It is possible to separate the files in folders created inside of the Services folder. So you can have a class that is inside of a folder weborb/Services/org/corlan/utils/. Another thing, usually you use a VO to wrap one piece of information. This could be stored inside of the same weborb/Services folder. You don’t have to do anything special to configure the VO, you just place it under the weborb/Services folder, and use it inside of your PHP service class.
In the “weborb/Services” folder, create a PHP file called MyService.php, and in the folder weborb/Services/vo create a PHP file called VOAuthor.php. Open the MyService.php page and paste the following code (you need to update the connection information for your specific database setup; to do this, look for the four constants at the top of the class):
This is the class you will call from Flex. It has two methods: one to get all the records from the table, and another to update the values for one record.
Let’s create the code for the Value Object, the data model. This is used by the MyService class to wrap one row from the table. Thus, the method getData() returns an array of VOAuthor, and the method saveData() receives one argument: the VOAuthor of the row that was changed. Open the file VOAuthor.php and add this code:
As you can see, this class is very simple; it just provides the same members as the fields from the table.
Creating the Flex application
Now, that you have the PHP code in place, you are ready to create the Flex code that will call the PHP class. I want the Flex application to have a button that gets the data from the server, uses a data grid to display the data, and enables the user to edit any cell (with the exception of the id field) within the data grid. Whenever a cell is edited, the update is sent automatically to the server and saved to the database as well.
First, be sure to select the Flex perspective from the top right icons of Eclipse.
The next thing you need to do is to configure the destination on the server in order to make calls to PHP classes from Flex. WebORB comes with all these configuration files created. If you go to the weborb/Weborb/WEB-INF/flex folder, you will find these files: services-config.xml, remoting-config.xml, and messaging-config.xml. First, you need to open the services-config.xml file and locate the opening node <channels>, and add after this code (pay attention to the uri attribute of the endpoint node; in my case the URL to weborb.php is http://localhost/weborb/weborb.php, though on your machine it could be different):
Save the file, and then open the remoting-config.xml file, and add a new destination:
You use this destination from Flex to make calls to the PHP services stored in the weborb/Services folder. You need to configure the Flex application to use the services-config.xml configuration file. To do that, open the properties panel for the project (right click the project name, and choose Properties), click on Flex compiler, and add a new command –services and the absolute path to services-config.xml file (see Figure 3).
Figure 3. Adding the -services compiler argument.
Click OK, and now you are ready to write the Flex code. Open the file flex_weborb.mxml if you haven’t already opened it, and paste this code:
I use the mx:RemoteObject to make the calls to the MyService PHP class from the server:
The destination attribute has the same value as the id value of the destination defined in the remoting-config.xml file (thus I am telling Flex that this is the destination I want to use). The source attribute points to the PHP class for which I want to make the calls. If the PHP class would have been in a folder that is in the Services folder, than I would use the folder names before the PHP class name with dot notation. For example, if you have MyService in weborb/Services/org/corlan, then the value of the source attribute is org.corlan.MyService.
Next I have defined the two methods I want to call on the PHP class (getData() and saveData()), and I set the result listeners for each method (these are the functions that will be called once the Flex application receives the response from the server).
For the UI I am using a DataGrid to display the data and edit inline the two text fields (first name and last name). I have a button to trigger the saving of the data back to server. On the DataGrid I have another listener registered for the end editing event, and the function registered gets called whenever something is edited in the DataGrid.
As you remember, I use a PHP object (VOAuthor) to wrap each row from the table. And I said that with remoting it is possible to get the conversion automatically from the PHP type to the proper ActionScript type. To do this, all you need to do is to create the ActionScript object. So just create a new ActionScript class with the package org.corlan, and the name VOAuthor. Paste this code in the class:
As you can see this class has the same members as the PHP class. It is very important to set the correct value for the alias attribute from the RemoteClass metatag. This tag tells the Flex application to what the corresponding server-side class is for this ActionScript class. In this case, the value vo.VOAuthor means that in the weborb/Services, there is a vo folder, and inside of it there is a VOAuthor PHP class.
And with that you should be ready to run the project and edit the data. To edit the data, just double click inside of a cell (see Figure 4).
Figure 4. The application with sample data.
WebORB handles the remoting as well as all the other frameworks. So there is nothing spectacular here. However, WebORB for PHP offers more than remoting. First of all, it offers data messaging (Publisher/Subscriber), so you can implement a chat or some other application that needs to push updates to all the connected clients. Though, I must say the only solution supported for PHP is AMF polling. Which means that the client does a request to the server from time to time to see if there is something new. This is a limitation of the PHP servers, as it would be very hard to implement a real data push over an open channel (COMET style maybe?). For example, for Java and ColdFusion servers you can have data pushing using polling or the RTMP protocol.
Secondly, WebORB comes with tons of sample applications, and a console that eases the testing of the services and lets you play with the samples. And finally, using the same console, you can generate some ActionScript code for any service. Basically, it generates a wrapper for the RemoteObject, and an ActionScript object for each of the VO used on the server. However, I didn’t find this to be very helpful, because it doesn’t generate for example the VOAuthor that I used in my example, but instead something like this: