Using Flex 4 Clients with the PHP Zend Framework Server

The key topic of this article is how to take advantage of the extensive server-side functionality provided by the PHP Zend Framework (ZF) Web application server on the server-side of Flex 4 client/server RIA solutions. You’ll learn that bootstrap loading of ZF and using selected ZF component classes are very easy to do. The big advantage though is that ZF allows you to provide compelling server-side functionality with noticeably reduced efforts writing PHP server-side code.

The article shows you, using easy to follow PHP code, examples on how to take advantage of using several ZF classes. The article demonstrates providing login authorization using Zend_Auth, sending login notice emails using Zend_Mail, and the huge time saver of writing less PHP database I/O code by using the Zend_Db ZF component class. You will also perform CRUD (Create, Read, Update, Delete) database I/O with just a few lines of PHP code for each of the CRUD operations. Finally, you will also see how to use Adobe AMF 3 client/server ActionScript 3 RemoteObject messaging code using the ZF Zend_Amf PHP component to handle the Adobe Flex AMF 3 messaging on the server-side.

The article concentrates on the notions of tying Flex 4 Web clients and/or Adobe AIR application to rich and capable PHP code classes on the server-side The combination of Flex 4 client and a PHP ZF Web application server is hard to beat when it comes to building capable RIAs. The name of our example application is FlexZF—showing the linkage between a Flex 4 server and a ZF PHP centric Web application server.

This article provides you with the following information takeaways:

  • Simple to deploy and use PHP bootstrap access to the Zend Framework
  • Full and complete understanding of Adobe AMF 3 RemoteObject messaging
  • Example code using of several base Zend Framework component classes
  • More functional Flex 4 client example code extended from the ADOBE® FLEX® 4 Tutorials on using the Flash Builder 4 Data/Services tools, specifically the Adobe Flex 4 Tutorials topics of:
    1. Creating PHP services for client applications
    2. Managing the access of data through paging
    3. Using data management to synchronize server updates

Requirements

Adobe Flash Builder 4—formerly Flex Builder 3 (includes the Flex 4 SDK)
Eclipse-based development environment for Flex. Supports visual and code-centric development, code hinting, visual debugging, and so forth. Includes the Flex 4 SDK and Flash Player 10
Alternately: Free Adobe® Flex® 4 Software Development Kit (SDK)
The Adobe® Flex® 4 Software Development Kit (SDK) includes the Flex framework (component class library) and Flex compiler, enabling you to freely develop and deploy Flex applications using an IDE of your choice.
PHP (both workstation and production server deployment required)
Web Server (both workstation and production server deployment required)
  • Apache HTTP Server
  • Alternately Microsoft IIS Web server (preinstalled with Windows XP or 7 Pro)
  • Note: Apache HTTP Serve is preinstalled on Macintosh OS X workstations and servers
MySQL Relational database server (both workstation and production server deployment required)
Zend Framework (Either Full or Minimal download will meet your needs)
Web Debugging Proxy (Optional tools. Tool use is highly recommended)
  • Charles
  • ServiceCapture
  • Note: The Flash Builder 4 Network Monitor tool provides an excellent view of client/server messaging and can replace use of Charles or ServiceCapture
Article Example files

Flex 4 / PHP Development References

Before you delve into deploying and evaluating the operation of the article’s example Flex 4 client and PHP server code, you may want to start by reviewing other blogs and articles on this topic, to get yourself up to speed on the development issues we will be talking about.

This article is an extension, with a more detailed study, of the ADOBE® FLEX® 4 Tutorials (PDF download), specifically:

  • Chapter 2: Installing the Flash Builder tutorial database, page 14
  • Chapter 4: Creating PHP services for client applications, page 22
  • Chapter 5: Manage the access of data through paging, page 31
  • Chapter 6: Using data management to synchronize server updates, page 45

The above information can also be found on the Adobe Flash Builder 4 online help or also available on your local workstation Adobe Community Help, click on the [Fb] button.

Note: this Adobe Community Help utility app is installed on your development workstation when you install Flash Builder 4, Cold Fusion, or any of the other Adobe Creative Suite packages.

Why use the PHP Zend Framework?

This one has an easy answer—to be able to design, develop, test, and design less PHP server-side code. I can create my entire set of database server I/O code in a manner of minutes, instead of the more traditional hours, if not days. Want to send an MIME formatted email from within RIA solution? The ZF does this with three lines of code. How about user login authentication and authorization using a MySQL database as the username/password login? This action is three lines of code to perform that operation, with a fourth line of code to check the authentication result.

What does the PHP Zend Framework Provide?

The ZF provides a rich set of PHP server-side functionality. Currently there are 66 base component classes in the framework. See the ZF Programmer’s Reference Guide. Wait a minute—am I going to have to master the use and application of all 66 ZF components? Well certainly not! The ZF tutorials, and to a degree, the ZF documentation, are targeted towards Model-View-Controller (MVC) RIA development, with the data handling (the model), display (the view), and RIA logic (the controller) in separate clusters of PHP scripts.

MVC design can get confusing and overwhelming very quickly. Plus there are many ZF components we will never require. A good example is the Zend_Validate component that is used for HTML form validation. Flash Builder 4 provides a rich set of form validation operatives. You mange your form within the client-side Flex 4 and not on the server-side as you might do within a HTML Web page. You will master less that a dozen of the 66 ZF base component classes and most of the time make frequent use of three or four ZF components. My message though is that using just a narrow set of ZF components will save you countless hours of server-side design and development.

Is the PHP Zend Framework Difficult to Deploy and Use?

TNo, it’s not difficult once somebody shows you how. I provide a PHP script, which when run, creates a bootstrap environment to manage your use and application of ZF classes.

The ZF is a large free and open-source library of PHP scripts. The ZF contains nearly 3,000 files in approximately 500 folders. The size of the full ZF distribution is slightly less than 30 MB, with the minimal versions coming in at 23.5 MB plus. By now you might have the feeling that ZF is “bloat-ware” that just don’t want to deal with. This is a worthy consideration that deserves some discussion.

Disk storage today is an inexpensive commodity, so I don’t see this as an issue. Then you might think that loading up 23.5 MB of PHP code is a huge overhead burden each time a server information request is made. The fact is that this does not happen. The Zend_Loader ZF component class only loads those classes required for a given ZF component class operation. Furthermore, many actions are not activated until required. They remain “lightweight.” For example you can instantiate a database connection inclusive of the all the typical required database connection parameters. But the actual connection to the database is not made until the connection is actually requested.

There’s a second approach too if you are concerned about large amounts of unused PHP code lying around on your server. You can choose the ZF components you want to deploy and use. Here’s why. First, ZF provides a large set of server-side components, most of which you will seldom, if ever, need to use. Second, ZF is a loosely coupled set of components with minimal dependency between components. You can use a set of ZF components without the requirement to master the use of the entire set of ZF components.

If you use the Flash Builder 4 Data/Services feature to establish your AMF 4 client/server messaging connection, the full ZF set of components is optionally loaded into the root of your Web site folder. This “full boatload” set of ZF components is far from necessary. I performed evaluation of the minimally required ZF components.

The required ZF components for the FlexZF client/server example in this article make up just 2.3 MB of Zend Framework code. The size of the PHP ZF code is only 547 Kbytes, if you just need the minimum set of ZF components for only AMF 3 client/server RemoteObject messaging. Furthermore, with just a couple of quick steps for each Web site on your workstation and/or production server, you can share your ZF components with multiple Web sites on a server. The minimum set ZF components for AMF 3 client/servers RemoteObject messaging is:

  • Zend_Amf
  • Zend_Auth
  • Zend_Config
  • Exception.php
  • Zend_Loader
  • Zend_Reflection
  • Registry.php
  • Zend_Server
  • Version.php (optional)

I will show you later in this article how you can separate the ZF components you require for your Flex 4/ZF project by using a PHP command line script to perform the select ZF component deployment. I will also show you how easy it is to share your selected ZF components with all Web sites on a Web server.

FlexZF Flex 4 Client and PHP Server Example Code Install

The FlexZF Flex 4 client and PHP Zend Framework server install instructions are in the Using Flex 4 with the Zend Framework.zip download package inside of the Install Information folder. Contained in the folder are two documents—one each for the Flex 4 client and PHP Service classes plus Zend Framework installs, respectively.

The install and configure steps are detailed enough that I thought it best to keep this information out of this base article where the discussions are more code operation centric.

About the upcoming article sections

The next article section is titled FlexZF Flex 4 Client and PHP Server Example Code Install. It is followed by three article major sections: Use and Application of the Server PHP Service Zend Framework Classes, The PHP Services Code Review and FlexZF Flex 4 Client Example Code Discussion. These sections respectively discuss the deployment and code operation. I suggest that you download and unzip the article’s FlexZF example code (Example Files, above)—even if you are not ready to install and configure the client and server code at this time. This way you can follow and review the mxml, ActionScript 3 and the server’s PHP code classes (including the Zend Framework), as the code’s install environment and operational functionality are reviewed.

Installing example Flex 4 client and PHP (Services and ZF) server code

An early-on task of the FlexZF Flex 4 client is to connect to the PHP services on the Web application server. It is recommended that you get the PHP (services and ZF) server code fully operational before starting with the FlexZF Flex 4 client.

The server install instructions, contained in the example code download, provides “how to” information on performing local to the server verification of server code operation.

About the FlexZF Flex 4 Client Example Code

I established the install of the FlexZF Flex 4 client example code using eight install steps over four install phases—numbered 0-3. I did this for a couple of reasons. Some of Flex 4 code is being auto-generated by the Flex Builder 4 Data / Services tool, which is worthy of reviewing the auto-install right after it happens. Additionally, I show a way to optionally extend the functionality of the example application. Taking a break between each of the install phases to briefly stop and review the code that just got installed should help your Flex 4 client code learning experience. The four phased installs inclusive of eight install steps are:

  • Phase 0: Step 1
    • Import Flex Builder 4 Project
  • Phase 1: Steps 2 thru 5
    • Connect the client to the server via an Adobe AMF 3 RemoteObject data connection using the Flash Builder 4 Data / Services tool.
    • Establish DataGrid paged data rendering
    • Enable data management to synchronize client to server data updates
      • With DataGrid binding to the server Employee data
  • Phase 2: Steps 6 and 7
    • Generate and code event handlers for the buttons
    • Add LSO (Local Shared Object) for login management
    • Add Flex 4 ViewStack with two Panel views:
      • Validated Login form
      • DataGrid display
  • Phase 3: Step 8
    • Remove and replace Add DataGrid record button with an Add form, with form validation.

Again, when installing the FlexZF Flex 4 client example code in four phases, I recommend that you stop after each install phase to review the newly installed Flex 4 code using the upcoming section titled FlexZF Flex 4 Client Example Code Discussion.

Use and Application of the Server PHP Service Zend Framework Classes

The Zend Server is a complete, enterprise-ready Web Application Server for running and managing PHP applications. And indeed it does have a purpose for many Web application server environments. The Zend Server licensing fees for light-duty web sites typically found for small and medium businesses is prohibitive. Additionally, the Zend Server does not run on Apple Mac OS X, making local workstation development with the Zend Server on the Macintosh impossible. You can rather easily use all or part of the Zend Framework without the requirement of using the Zend Server. And that is what this section is all about.

The Zend Framework Application Server

A minimum reason for using the ZF application server is to take advantage of using Adobe AMF 3 RemoteObject client/server messaging. The FlexZF Flex 4 example application purposely uses more of the ZF components than just the ZF Zend_Amf component so that I can provide more than one demonstration example of using ZF components. It this section I will discuss how to deploy these scenarios: 1) minimum set of components for AMF 3 message, and 2) the more fuller ZF component set use example.

The Adobe Action Message Format — AMF 3 Specification, May 5, 2008, is available for your download and review.

What’s my reason for recommending use of a few ZF components? I’m finding the I have to write less server-side PHP classes, which means noticeably less testing and debugging. Recently I had a project where I needed to send an administrative each time a user logged into the application. I did a little studying of the ZF Zend_Mail component docs and was pleased to learn that I could format and send the email with just four lines of PHP code. Yikes! How easy! This exercise was my first decision factor in deciding to write the InsideRIA article so that I could share with others what I learned.

Where to Deploy the Zend Framework

I normally install the ZF in the Web server root on my workstation as shown in Figure 1. This is so that the framework can be shared with multiple Web sites under development and/or valuation. You’ll see shortly how we go about the sharing of the Zend Framework.

FlexZF_Figure_1.jpg
Figure 1: Zend Framework Installed in the Web Server Root

Note: It is recommended that you install the Zend Framework outside of your Web server root on your production server, for security purposes.

For this FlexZF article, I installed the Zend Framework within the Web site folder, as shown in Figure 2. This approach was for the convenience of making the deployment task simpler, if you elect to install and evaluate the FlexZF client / server solution example.

FlexZF_Figure_2.jpg
Figure 2: The FlexZF Example Server-side Code, Including the Zend Framework

Selective Zend Framework Component Deployment

The “minimal” set of downloadable ZF components is 23.5 MB. We don’t need all of these ZF components. And while disk storage is most inexpensive, you don’t need to drag all of the ZF components to you development workstation and ultimately your production Web server.

I did a bit of research in order to identify exactly that the minimum set of ZF components required for the FlexZF Flex 4 client / server example. I identified that the required size of ZF components was just 2.3 MB. Principally the FlexZF article example deals with three ZF component classes:

  • Zend_Auth
  • Zend_Db
  • Zend_Mail

My research evaluation showed me that the above three components had other ZF components. So the entire 2.4 MB can be summed up as follows (with some of the ZF component dependencies identified):

  • Zend_Amf => Zend_Amf_Server
  • Zend_Auth => Zend_Auth_Adapter
  • Zend_Config => Zend_Config_Ini
  • Zend_Db => Zend_Db::factory, Zend_Db_Adapter_Exception, and Zend_AmfDb_Adapter_Exception
  • Zend_Exception
  • Zend_Loader => Zend_Loader_Autoloader
  • Zend_Mail => Zend_Mail_Transport_Smtp
  • Zend_Mime    Used by Zend_Mail
  • Zend_Reflection    Used for Flex 4 Data/Services object introspection
  • Zend_Registry    Used by Zend_Db and Zend_Validate
  • Zend_Server    Used by Zend_Amf introspection and Zend_Reflection
  • Validate    Used by Zend_Auth

I found the above exercise of selecting a minimal set of ZF components an interesting endeavor. I got curious enough about the minimal size of ZF components required if you only wanted to use the Zend_Amf component for AMF 3 Remote object messaging. You may have observed that the Flash Builder 4 Data/Services tool installs the entire 23.5 MB ZF. Surprise! The minimum required set of ZF components required for Adobe AMF 3 RemoteObject messaging only is 575 KB. The minimum required set of ZF components for AMF 3 Remote object messaging only, consists of:

  • Zend_Amf
  • Zend_Auth
  • Zend_Config
  • Exception.php
  • Zend_Loader
  • Zend_Reflection
  • Registry.php
  • Zend_Server
  • Version.php (optional)

One has to wonder why Flash Builder 4 drags in entire 23.5 MB ZF when only 575 KB of ZF code is required. I like the idea of minimal ZF component deployment and built two PHP scripts, which you run from your PHP command line to deploy only a desired set of ZF components. You will find these two scripts in the Using Flex 4 with the Zend Framework.zip example file download, in the ZendFrameworkGenScripts folder. One PHP script, genFlexZF_ZendFramework.php deploys only the ZF components required for the FlexZF client / server example. The other PHP script, genZend_Amf_ZendFramework.php, deploys only the ZF components required for a Zend_Amf component AMF 3 remote objet connection.

The way you use either PHP script is quite simple and only two-steps:

  1. In each respective script there is a PHP variable named “$dest” approximately 30 lines down from the start of the PHP script. Set the “$dest” variable to the absolute data path of where you want to selectively deploy your ZF components.
  2. Run the respective script from command line using your PHP (CLI) script engine with the script placed in the root folder of your ZendFramwork unzipped download. For example: “ZendFramework-1.10.7”

Bootstrapping the Zend Framework (Loading the ZF Class Files)

Earlier, I stated that you could deploy and use any or all of the ZF without requiring Zend’s Zend Server. This sub-section will tell how to do this. Refer to the earlier Figure 2. There are three PHP scripts here that perform the bootstrap loading of the ZF class files. These PHP scripts are named:

  • site_config.ini
  • gateway.php
  • zendLibrary.php

I’ll save the conversation regarding the use and application of the zend_library.php PHP script for then next section titled The PHP Services Code Review.

FlexZF_Figure_3.jpg
Figure 3: Linkage of the Flex client and the PHP server build

Refer to Figure 3 above. First, the two dotted-line linkages exist only during the Flex client/server development process. These linkages, or for that matter, all Flash Builder 4 IDE system elements, do not exist on your production Web server—see the following note for further details.

Note: I keep the services-config.xml file in the Web server root config folder only as a consistent project data storage location. You can place this XML file anywhere on your development workstation. The services-config.xml file is not deployed to the production server when the development project is released.

Per Figure 3, the services-config.xml file, residing in the Web server root, provides the project build linkage information. Details about how Flash Builder Flex 4 client build linkages to the PHP server are configured and used are in the section titled The PHP Services Code Review.

Also shown in the Web site folder in Figure 3 is a file named gateway.php. This file provides the linkage from your Web site’s generated Flash file to your Zend Framework Web app server. The gateway.php PHP script reads the “zend_path” parameter in the site_config.ini file to know where the ZF Library folder is located. The gateway.php file contains the code to establish the Zend_Loader ZF component, which can, in turn, load other ZF components, as they are required, starting with the Zend_Amf component. Exactly what the gateway.php does and how it works will be obvious by a review of the PHP code statements.

In closing here, I should point out that you can use the above three ZF bootstrap PHP scripts, site_config.ini, gateway.php, and zendLibrary.php, with any or all of your Flash Builder 4 Flex 4 / PHP centric Web application server solutions. The install procedure is:

  1. Copy these three PHP script files to your Web application server root.
  2. In site_config.ini, set the “webroot” parameter to the absolute (not relative) data path to your Web application server root of your server environment.
  3. In site_config.ini, set the “zend_path” parameter to the absolute (not relative) data path to the folder of your Zend Framework install.

That’s all there is to using these three ZF bootstrap files. Again, remember that multiple Web sites on a given Web server can share the same Zend Framework Library. The site_config.ini, “zend_path” parameter, in each of your Web site folders, points to the absolute (not relative) data path to the Library folder of your Zend Framework install. Simple, and it works seamlessly.

My Experience with Zend Framework Mastery and Development

The ZF online documentation is lacking and not easy to follow. There are little or no complete sets of example code. Instead the documentation shows isolated sets of PHP statements without an idea of how sets of API calls might be implemented to produce a desired result. I’m not 100% sure why the ZF documentation was written this way. Is it developers writing for developers?

Furthermore, ZF was originally developed to provide the core components of a MVC (Model-View-Controller) Web application. We are not developing a solution where our PHP code 100% fits into a MVC structure. Instead our Flash Builder 4 built FlexZF Flex 4 client provides the MVC view, model, and the controller portions of front controller and command generator. What is left on the PHP server side—if we followed the MVC notions—are the business delegate, service controller, and the actual services. Accordingly, with Flex 4/PHP centric RIAs, we really only care about using a smattering of ZF components. And those are a select few to understand and master their use and application. This is one of the unpublished secrets in the use of Flex 4 client with ZF for the PHP server-side components. And that is to determine a select few ZF components and master their use and application.

I think that this somewhat minimal ZF mastery approach effort to use a small handful of ZF components will save you countless hours of designing, developing, testing, and debugging starting from scratch PHP code.

I’ll describe to you how the process I used to create API calls to the ZF components was successful for me. I observed that the ZF component documentation was mostly small groups of PHP statements and nothing really concrete in the way of a complete sequential action that produces an end result, as stated earlier. I’ll discuss how I test and debug PHP in the upcoming sub-section How I test my PHP service Classes in next section The PHP Services Code Review.

Therefore, my approach was to write and expand the ZF component calls in my PHP service object method a few step as a time. I would then view the resultant behavior and study the ZF component documentation to determine what I needed to do next. Surprisingly, this method of stepwise refinement got me there fairly quickly.

As an aside, but somewhat related, I was most pleased on how quickly I got the PHP service class methods operational by using the Zend_Db component for MySQL server database I/O. Even more enjoyable was the fact that my code worked first time out without much, if any, debugging.

The PHP Services Code Review

Refer to the earlier Figure 2 and note the services folder inside the FlexZF Web site folder. Note that this folder contains three PHP script files, of which two are structured as PHP classes:

  • EmployeeService.php
    • Base FlexZF PHP service class
  • ZFMail.php
    • PHP service class to send login notification emails.
    • Instantiated and used by EmployeeService.php
  • EmployeeServiceTest.php
    • Use case test code used to evaluate EmployeeService.php class method operations

This FlexZF Flex 4 RIA section is a code review discussion of these two PHP service classes and the PHP script to use case test the object methods contained in these two classes.

What are PHP services?

The server-side PHP service class or classes is where all core server-side operations take place. This is the core “business logic” where all server-side work (mostly database I/O) happens. A Flex 4 client instigates asynchronous client-to-server messaging using the Adobe AMF 3 messaging protocol by using ActionScript 3 RemoteObject calls.

Refer back to Figure 3 and note the gateway.php file that was discussed earlier. The ZF bootstrap PHP script file, a.k.a., gateway.php, knows where the ZF is so that it can use the Zend_Loader component to load other ZF components as required, when needed. So how does the gateway.php bootstrap PHP script file know the Web server service folder name? If you look in the site_config.ini, file you will notice this entry near the near the end of the .ini file: amf.directories[]=services. This entry tells the ZF Zend_Amf component the name of the services folder. The gateway.php file passes the services folder name information to the ZF Zend_Amf component during the ZF component load. Subtle, huh? And yes, you could change the services folder name to something nonstandard, if that is your desire.

The Flex Client to Server PHP Services Linkage

In this section and the previous one, I’ve been discussing that gateway.php is the Adobe AMF 3 messaging entry point from client to the PHP server services and the ZF components. Until now, I have not told you how the Flash Builder Flex 4 client knows about the gateway.php located in the Web server root. Now is a good time to talk about how and where this linkage is created.

When you create a Flash Builder 4 Flex 4 project, where the Application server type is set to PHP, you need to establish an end point to that Web site. This endpoint is required in addition to setting the Web root and Root URL in the Flash Builder 4 properties. You must also pass a services parameter to the Flex Compiler property, which is the path to a services-config.xml file located anywhere you choose on your workstation. The Flex Compiler, Additional compiler argument, parameter looks like this on my Mac OS X workstation, which is a path to my services-config.xml file in the config folder in my FlexZF Web server root folder:

FlexZF_Figure_4.jpg
Figure 4: Flash Builder 4, Additional compiler argument property

The entry point is contained in an XML element tag in the services-config.xml file that looks like this:

<endpoint uri="gateway.php" class=
    "flex.messaging.endpoints.AMFEndpoint"/>


And that is the linkage from Flash Builder 4 build properties to the gateway.php file in the root of my FlexZF Web server. Back up and again take a look at Figure 3 where you will see the linkage from Flash Builder 4 to the gateway.php file.

Caveat: now that I’ve told you about how to establish an endpoint to gateway.php by adding a Flash Builder 4 Additional compiler arguments property, I’m going to tell you that this Flex 4 build step is not necessary when using the Flash Builder 4 Data/Services tool to establish the client / server data remoting connection. This is because, by default, the Data/Services tool is looking for gateway.php in the app’s Web server root. You will develop an AMF 3 RemoteObject solution where you do not use the Data/Services tool to auto-generate the client side code, perhaps sooner rather that later. Instead you manually write the AMF 3 RemoteObject ActionScript 3 code. You need to establish your services-config.xml endpoint in this case. You need be fully aware of the situation where the server endpoint establishment is required.

The EmployeeService.php services Class Code Review

The EmployeeService.php services class provides eight public methods; with one method for user login authentication and the remaining seven methods for MySQL database I/O to/from the employees and users database tables. Of the seven database I/O methods, five provide the base standard CRUD (Create, Read, Update, and Delete) services. The remaining two methods are for retrieving data records in the FlexZF data grid display on a paged display bases. The method names are:

  • authenticate
  • getAllEmployees
  • getEmployeesByID
  • createEmployee
  • updateEmployees
  • deleteEmployees
  • count
  • getEmployeesPaged

The ZF Zend_Db component is instantiated when the EmployeeService.php services object is instantiated by the ZF Zend_Amf component. What is not so obvious is how the ZF Zend_Db component instantiation—via the object factory call, at line #28, shown here, even works:

$this->db = Zend_Db::factory('Mysqli', $params);

In other words, how does the Zend_Db factory call to establish the ZF Zend_Db component know where the Zend Framework is? Well it’s far from obvious, so I will explain how it happens. When the gateway.php file in the root of my FlexZF Web server is called it instantiates the ZF Zend_Loader component, which is looking ready, willing, and able to load other ZF components as they are required by your PHP code. Lots of ZF magic is happening underneath that you don’t need to concern yourself with, other than know how to take advantage of the rich functionality. This ZF component object factory call I just described is both convenient and powerful, but also most subtle regarding how and why.

The EmployeeService.php services object authenticate method is worthy of a brief discussion. There is a users MySQL database table containing the user name and password of authenticated users of this employee database table solution. Authenticating a user’s login via the users MySQL database table takes just three lines of PHP code to let the ZF Zend_Auth component do all the login authentication work for you. Those three lines, by number, are 50, 51, and 57. The balance of the authenticate method is to sent a pass/fail (true/false) login status back to the FlexZF Flex 4 client. And lines 64 and 65 make the call to send the login administrative notification email, which is discussed in the next sub-section.

There’s a functional description for each of the methods in the EmployeeService.php services source code file. I’m not going to repeat that information here. One point of interest in the source code file is that with the exception of the count method, all the method calls are performed by calls to theZF Zend_Db component. I made additions to each method as a PHP comment identifying what the PHP database I/O call might consist of if the ZF Zend_Db component API calls were not being used. You should observe that API calls are much shorter when calling the ZF component APIs.

There’s another productivity improvement here is that is not obvious until you develop your own PHP services. And that is that the database I/O calls required zero debugging. Call a ZF Zend_Db component and it works. Period! I had this entire EmployeeService.php services class fully operational in just over two hours. Past efforts for the same results not using ZF components have typically taken two to three days, including testing, debugging, and refactoring.

The ZFMail.php services Class Code Review

You saw in the previous sub-section, about the EmployeeService.php services class, that this class instantiated and called respectively the class at EmployeeService.php lines 64 and 65.

The instantiation of the ZFMail.php class establishes the ZF Zend_Mail component at lines 14 and 15. The EmployeeService.php services class then calls the sendMail method in theZFMail.php class passing into the method and object with all the email send parameters and message content. Lines 21 through 26 format and send the email. Line 24 calls the genMail method to format the HTML text for the email body. PHP DOM is used to generate the HTML. How PHP DOM performs the message body HTML tags and content generation is beyond the scope of this article. You can do this just as well with some simple use of HTML tags. If this is a bit much, then just send a plain text message.

Note: You will have to establish your email provider SMTP parameters for MailHost, UserName, and Password const parameters in ZFMail.php, in order to use the ZFMail.php services class to send administrative email notices. If you would prefer the run the FlexZF example application and not sent login notice emails, then comment out lines 64 and 65 in the EmployeeService.php services class

How I Test My PHP services Classes

The EmployeeServiceTest.php file, also located in the services folder, is neither a services not PHP object file. Instead this is a file I used to test the operation of the EmployeeService.php services class by running this PHP script from the PHP command line (the PHP CLI scripting engine). I typically test one object method call at a time by un-commenting one of the respective tests contained in this test suite. I run one or more of these test suites anytime changes have been made to one or more methods in the EmployeeService.php services class file.

The EmployeeServiceTest.php file first instantiates the EmployeeService.php services class into an object. Then calls a method within the object, typically passing in a test parameter.

When using the EmployeeServiceTest.php file there is a very important configuration step you need to take when instantiating the EmployeeService.php services class for testing purposes. The normal client-to-sever messaging operation is:

  • FlexZF client makes a RemoteObject AMF 3 message call to the PHP Web application server.
  • The gateway.php PHP script is called in the PHP Web application server.
  • The gateway.php PHP script loads the ZF Zend_Loader and also calls the ZF Zend_Amf component.
  • The ZF Zend_Amf component instantiates the EmployeeService.php services class into an object and calls the FlexZF client requested EmployeeService.php object method.
  • Database I/O (and other) work is done and a (typically data) result is returned to the FlexZF Flex 4 client for data display update.

Bad news . . . the above steps 1 though 5 never occur when instantiating the EmployeeService.php services class from the EmployeeServiceTest.php file. And the operation depends on the EmployeeService.php services class and requires the ZF Zend_Loader to be present for stand-alone testing. The “how to” instructions are in lines 7, 8, and 9 of the EmployeeService.php services class file.

Well, the good news is that there is a solution. I created a ZF Zend_Loader bootstrap loader file for stand-alone testing of PHP service objects that need to load and use ZF component classes for their basic operations. The name of the file is zendLibarary.php and it is located in the root of the FlexZF Web server root. And all you need to do is include this file when you run the EmployeeService.php services in a test stand-alone environment.

Caveat emptor, be sure to again comment out the line 9 include when you’re through running stand-alone tests. Otherwise Flex 4 client to PHP Web application server messaging will not work and it may drive you crazy as to why things are not working when the Flex 4 client refuses to render Employee data in the panel’s DataGrid.

This little tidbit tip alone my be worth this entire InsideRIA blog article in that you have a convenient and easy way to run, review, and evaluate the operation of ZF component classes in a convenient stand-alone way.

You might want to review the zendLibrary.php file to see how it is structured and works.
  1. It provides an convenient and easy-to-use ZF Zend_Loader component test environment such that you can call ZF component objects and run their published APIs to test their operation and return results. (This is how I made ZFMail.php class fully operational.)
  2. If you sometimes build Web sites using HTML via Dreamweaver or your favorite text editing, the zendLibrary.php is a great way to take advantage of ZF components with PHP code. (On example that comes to mind is that the Zend Framework provides a very capable form entry validation solution.)

FlexZF Flex 4 Client Example Code Discussion

The FlexZF Flex 4 client install procedure is done in four distinct phases. I did this so that you can examine and review that code at the end of each phase. The four install phases are numbered 0 though 3. Each phase consists of one or more install steps. You should return here as you complete each of the FlexZF Flex 4 client install phases for a code review analysis of the code installed during that phase.

The key phase is the second phase, phase 1 where you use the Flash Builder 4 Data / Services tool in order to auto-generate the AMF 4 RemoteObject messaging between the client and server. Phase 1 install is based on the ADOBE® FLEX® 4 Tutorials document, specifically the chapters:

  • Chapter 2: Installing the Flash Builder tutorial database, page 14
  • Chapter 4: Creating PHP services for client applications, page 22
  • Chapter 5: Manage the access of data through paging, page 31
  • Chapter 6: Using data management to synchronize server updates, page 45

Alternately, the above information can also be found in two other resources:

  1. Adobe Flash Builder 4 online help
  2. Adobe Community Help, click on the [Fb] button.

In either of the above documentation resources, navigate to:
Adobe Flash Builder 4

  • Tutorial on data access with Flash Builder 4:
    1. Installing the Flash Builder tutorial database
    2. Creating PHP services for client applications
    3. Manage the access of data through paging
    4. Using data management to synchronize server updates
Note: the above Adobe Community Help package is installed on your PC workstation when you install Flash Builder 4, Cold Fusion, or any of the other Adobe Creative Suite packages.

Phase 0: Step 1. Import Flash Builder 4 Project

This base install phase had you import the FlexZF Flex 4 project into your Flash Builder 4 IDE.

Code-wise there is not much to discuss here other than to say the starting index.mxml code is just a bit more than you would see by establishing an initial Flash Builder 4 project with an Application server type of PHP. There are, however, three project starting code additions to reduce just a bit of your initial work. These three code additions are:

  1. An ActionScript 3 initData method is established for subsequent install phase utilization.
  2. A nearly empty Spark Panel layout container is in place so you can start creating a data display during the next Flash Builder 4 install phase.
  3. Four buttons are established for future install tasks. The four buttons do not yet have click handlers established.

Figure 5, provides a view of what you will see after running the imported FlexZF Flash Builder 4 project.

FlexZF_Figure_5.jpg
Figure 5: FlexZF Flex 4 Phase 0 Install Result

Phase 1: Steps 2 thru 5: Connect to Data / Services

You will see the display shown in Figure 6, after completing phase 1, steps 2 through 5 install steps, and running the FlexZF Flex 4 client. The Flex 4 code that was mostly auto-generated by your install steps is discussed following Figure 6.

FlexZF_Figure_6.jpg
Figure 6: FlexZF Flex 4 Phase 1 Install Result

During this install phase, you performed the following three procedures:

  1. Client to server AMF 3 data connection using the Flash Builder 4 Data /Services tool.
  2. Established server to client DataGrid paged data rendering
  3. Enabled data management to synchronize client to server updates

Flex 4 client install differs here from the two Adobe tutorials on this topic—one for data paging, and the second tutorial on data management—I have combined both of these tutorials into one so that you have data paging combined with data management to synchronize client to server updates.

Following is the phase one install code discussion.

Let's talk about the Flex 4 code that got generated when running the Flash Builder 4 Data/Services tool. First, notice the script section within your index.mxml page. This is the ActionScript 3 code that performs the AMF 3 RemoteObject call to obtain the data from the MySQL `fb_tutorial_db`.`Employee` database table to render this information in the Flex 4 client DataGrid. You set the AMF 3 remote messaging to call the PHP getEmployeesPaged() method on the EmployeeService object to perform the server-side of the DataGrid display.

The AMF 3 RemoteObject calls are performed asynchronously so that the user's experience with the client are not blocked while waiting for the data to arrive from the server to the client via AMF 3 formatted messaging. Flex 4 uses a CallResponder declaration to eliminate remote messaging blocking and waiting. You can view this CallResponder declaration on line 29 in your index.mxml code module. Think of the CallResponder as a storage point location for received data. In a sense, the CallResponder is the AMF 3 asynchronous messaging broker.

A token is passed to the CallResponder during the client-to-server remote message startup--the action is the DataGrid creation complete. ("Hey, I’m ready to render some data in my DataGrid.") The actual AMF 3 remoting call is made at line 21 to the PHP method employeeService.getEmployessPaged(). And the left-hand assignment of this remoting message call is assigned to the getEmployeesPagedResult.token CallResponder, which was auto-defined for you at line 29 of index.php. The CallResponder listener, which is located within the DataGrid, at line 37, is "{getEmployeesPagedResult.lastResult}". Summarily, when the data is from the server's database arrives at the CallResponder's token, where the DataGrid is listening for the "lastResult". Then when the data is received it is rendered in the DataGrid. The order of AMF 3 remote messaging is:

  1. dg_creationCompleteHandler() is registered as the handler for the DataGrid's creationComplete event.
  2. The DataGrid's createComplete event is fired and the dg_creationCompleteHandler() method is called
  3. The employeeService.getEmployeesPaged() method is called which returns a token (we'll see this code in a bit)
  4. The asynchronous call to employeeService.getEmployeesPaged() completes and the DataGrid is updated to the Employee data stream via the CallResponder getEmployeesPagedResult.lastResult, which is the property that contains the last remoting service call result.

One last thought here. And that is where is the employeeService.getEmployeesPaged() ActionScript 3 code and how did it get created? This code was auto-generated when you performed the Flash Builder 4 Data/Services operation. The code is linked in via an XML namespace as an attribute at the top <s:Application XML tag, specifically the XML attribute: xmlns:employeeservice="services.employeeservice.*"

If you look in the Flash Builder's src folder you will find a 'services.employeeservice' folder. This is accessed by the above 'employeeservice' namespace. Line 340 of the '_Super_EmployeeService.as' file, that contains the following code:

/**
   * This method is a generated wrapper used to call the 'getEmployeesPaged' operation. It returns an mx.rpc.AsyncToken whose 
   * result property will be populated with the result of the operation when the server response is received. 
   * To use this result from MXML code, define a CallResponder component and assign its token property to this method's return value. 
   * You can then bind to CallResponder.lastResult or listen for the CallResponder.result or fault events.
   *
   * @see mx.rpc.AsyncToken
   * @see mx.rpc.CallResponder 
   *
   * @return an mx.rpc.AsyncToken whose result property will be populated with the result of the operation when the server response is received.
   */
 public function getEmployeesPaged() : mx.rpc.AsyncToken
 {
     var _internal_operation:mx.rpc.AbstractOperation = _serviceControl.getOperation("getEmployeesPaged");
     var _internal_token:mx.rpc.AsyncToken = _internal_operation.send() ;

     return _internal_token;
 } 

Details of this auto-generated code and how it works are beyond the scope of this article. Note though that there are two Adobe® Flex® 4 Language Reference API references in the comment section of the above code listing (mx.rpc.AsyncToken and mx.rpc.CallResponder), for those who are interested in more details regarding asynchronous remote messaging.

Phase 2: Steps 6 and 7: Generate and code event handlers for the buttons complete

You performed generate and edit in code for event handles for the four buttons, during phase 2, step 6 of the install instructions. This install exercise was following one of Adobe’s tutorial exercises with some code modifications to meet the specific requirements of our article example FlexZF Flex 4 client.

The application view of the phase 2, step 6 exercise, when run, looks identical to the example app run of phase 1. The difference, of course, is that the four buttons now have a click handler method that perform the respective actions of DataGrid data Add, Delete, Revert, and Save All Changes. These buttons are calling methods to perform their defined actions by calling methods in the employeeService class, which was auto-generated during Flash Builder 4 Data/Services tool operation. Again, the details of this auto-generated code and how it works are beyond the scope of this article.

I had you replace your index.mxml with the content of index2.mxml and then run the example, in phase 2, step 7. Suddenly the FlexZF example’s operation noticeably changed. The DataGrid and four-button display panel is the same, however now you have to go through login dialog in order to gain access to the Employee DataGrid display. See Figure 3 for the login example page.

Note: the valid Username and Password required for login can be found in the `ft_tutorial_db`.`users` database table entries. You can view this data with your MySQL client or by opening the users_table.sql database schema file located in your FlexZF Web server root folder inside the ‘config/Database Schemas’ folder.

What was added to your example application was authenticated access to the Employee data via a login screen, which uses a MySQL database to hold the authentication credentials (Username and Password).

Next, I’ll review the code added to index.mxml via your cut and paste install operation of phase 2, step 7.

FlexZF_Figure_7.jpg
Figure 7: FlexZF Flex 4 Phase 2 Install Result

The most significant addition to index.mxml is an mx:ViewStack within the Spark Panel layout container. The first Spark Navigator view is the added login form, encompassing the code from line 124 through line 144. Line 138, the Login button click calls the clickAuthenticate ActionScript 3 method starting at line 94. The login form contains form validation driven from the mxml code at lines 116 and 117. Line 95 checks for validated Username and Password form data before sending it to the server-side EmployeeService PHP class for login authentication, using the MySQL `ft_tutorial_db`.`users` database table data.

The login return status from the server-side EmployeeService PHP class is a Boolean value, true for authenticated, false otherwise. The login result is retuned from the server to the handlerAuthenticateResult event handler method at line 76. The AMF 3RemoteObject return to the event handler was established as follows:

  1. Spark CallResponder was established at index.mxml line 111 identifying the handlerAuthenticateResult event handler method as the return callback.
  2. Line 100 shows the employeeService.authenticate call to the server result assigned to the authenticateResult.token—which was established at line 111.

Let’s again move back to the handlerAuthenticateResult event handler method at line 76, if the CallResponder authenticateResult.lastResult is returned true (authenticated login) then the code optionally saves to Username and Password off to a Local Shared Object (LS0). Line 90 performs the Spark Panel mx:viewStack change from the login state to the dialog view, as shown earlier in Figure 6.

Just mentioned, in the last paragraph, was that the Username and Password are optionally saved off to a LSO. This action is to make it convenient for the user in the Username and Password are restored to the login dialog at application startup, this saving the effort to recall and restore this information to the login dialog.

The optional saving of this login data is determined by the Remember Password check box in the dialog. Saving the login data is optional for security purposes in that if login is enabled without the requirement of knowing the Username and Password then the user’s access to the Employee data can be gained when the user’s workstation is unmanned.

The FlexZF Flex 4 client’s LSO is partially managed on the application startup method initData at line 22. Line 24 loads the LSO into application memory. If this is a first-time startup, then the initial LSO is established by the AS 3 code in line 26 through 32. Otherwise, the second and all future application logins are loaded into the application, at startup, at lines 33 through 36.

Information on how to use and apply LSO is found in the Flex 4 documentation at the following navigation hierarchy: Home / Using Flex 4 / Application architecture / Security / Writing secure applications / Storing persistent data with the SharedObject class

This is a quick and easy application extension for more secure login access by not exposing your login password over the Internet for others to possibly view and use for illegal access. You comment out line 100 and uncomment line 99. The difference is the login password is now sent to the server, over the Internet, as 128-bit MD5 hash encryption. We must then compare our encrypted password with an encrypted password contained in the MySQL `ft_tutorial_db`.`users` database table entries for login authentication. Open the users_table.sql database schema file located in your FlexZF Web server root folder inside the ‘config/Database Schemas’ folder. Notice the set of MD5 encrypted login passwords. You replace this present set of database passwords in the second set database INSERT records. The plain text passwords in the INSERT record are MD5 encrypted as they are posted into the database table. Each password is wrapped with a MD5() hash encryption function call during the database table load.

Phase 3: Step 8: Add record button replaced by and Add form with form validation

The Phase 3, step 8, install instuctions had you cut and paste replace code from the index3.mxml example file into your index.mxml file in your FlexZF Flash Builder 4 project. This install exercise provides an added bonus example. What happens is that the Add (Employee) button is removed and replaced by an Employee Add form. This display change is shown in Figure 8.

A principle reason for a change like this is to validate the new Add Employee user data form input before it is remotely posted to the server-side database. Programming-code-wise, the Add form function addition is fairly straightforward.

First the addButton_clickHandler AS 3 method at line 48 of the phase 2 install is replaced by the same method name, starting at line 59. The new Add form is contained in line 207 though 234. This is a very traditional Flex 4 form, which does not require discussion other than to say the Add button code, at line 231, has a click handler to call the addButton_clickHandler ActionScript 3 method.

The Add form input data is validated by the Flex 4 mxml code in lines 155 through 158. Each Add form text input is checked for valid or invalid date and sets the respective boolean properties at lines 23 through 26.

FlexZF_Figure_8.jpg
Figure 8: FlexZF Flex 4 Phase 3 Install Result

Coming back again to the new addButton_clickHandler ActionScript 3 method starting at line 59 we set a formValid boolean that is a logical summation of all the form input fields. If one or more Add form fields are invalid then the code lines 65 through 77 determine what invalid Alert dialog message to display (line 76). After the user clicks on the Alert okay button the application returns from the method without posting the new Employee data from the Add form—because it’s invalid (i.e., not incomplete).

The addButton_clickHandler ActionScript 3 method conditionally jumps to line 70, of index.mxml, if Add form data is valid (i.e., complete). Lines 79 thru 83 load the earlier instantiated—line 71-- Employee object with the Employee data from the Add form. Code lines 84 and 85 post the Add form’s data to the DataGrid display, while line 85 commits the Employee data to server’s MySQL database using the auto-generated earlier by the Flash Builder 4 Data/Services tool.

It is interesting to note that what happens via index.mxml lines 84 thru 86 is equivalent to our previous install Phase 2 by the Add (then edit into the new DataGrid entry) and then subsequently clicking on the Save All Changes buttons respectively.

Closing thoughts

The emerging software application development opportunities are on mobile "smart phone" platforms. Imagine, for a moment, the phone being the Flex 4 client performing CRUD operations with a remote PHP Zend Framework Web application server. Can you apply easily what you've learned from this article’s mobile-based solution? You certainly can and it’s easier to accomplish than you might expect.

You would simple take what you've learned here and create an Adobe AIR application instead of a Flex 4 Web application as we built in the article example. For your build, you change your endpoint>, defined in services-confilg.xml from this:

<endpoint uri="gateway.php" class=
    "flex.messaging.endpoints.AMFEndpoint"/>


to a specific URL, something like this:

<endpoint uri="html://www.domain.com/web_site/gateway.php" class=
    "flex.messaging.endpoints.AMFEndpoint"/>


Next you would package your application using the Adobe AIR for multiple mobile devices. Adobe AIR allows developers to use familiar Adobe tools, or any text editor to build their applications and easily deliver applications that work across operating systems. Additional information regarding Adobe AIR for mobile devices is available at Adobe Mobile and Devices Developer Center. To understand the new support for mobile application development, read Narciso Jaramillo’s Mobile Development Using Flex SDK "Hero" and Flash Builder "Burrito" article.

About this Entry

This page contains a single entry by Pete Mackie published on January 3, 2011 9:00 AM.

Hands On With The Logitech Revue was the previous entry in this blog.

If You Can Make It Here Part 3 is the next entry in this blog.

Find content using the provided navigation or look in the archives to find all content.

Authors

Archives

This content archive is licensed under a Creative Commons License.