Creating PHP services for client applications

You can create applications with Flex that access services from a wide variety of technologies. These technologies include:

  • ColdFusion

  • PHP

  • HTML (REST-style) services

  • Web services (SOAP)

After creating a service, it is a good idea to test the service before accessing it from a client application.

The principles of creating and testing PHP services can be applied to other service technologies.

Create a PHP class that implements a service

The service you create in this tutorial accesses the fb_tutorial_db database. For information on installing this database, see Installing the Flash Builder tutorial database.

  1. In your web root, create a folder named PHPService. Within that folder, create another folder named services.

  2. In your favorite PHP editor, create the following PHP file, which implements EmployeeService. Name the file EmployeeService.php. Place it in the PHPService/services folder.

    <?php 
    /** 
     * This sample service contains functions that illustrate typical service operations. 
     * This code is for prototyping only. 
     *  
     *  Authenticate users before allowing them to call these methods. 
     */ 
    /** 
     * The constructor initializes the connection to database. Everytime a request is 
     * received by Zend AMF, an instance of the service class is created and then the 
     * requested method is called. 
     */ 
    class EmployeeService { 
      var $username = "USERNAME"; 
      var $password = "PASSWORD"; 
      var $server = "localhost"; 
      var $port = "3306"; 
      var $databasename = "fb_tutorial_db"; 
      var $tablename = "employees"; 
      
      var $connection; 
      public function __construct() { 
        $this->connection = mysqli_connect( 
                           $this->server,  
                           $this->username,  
                           $this->password, 
                           $this->databasename, 
                           $this->port 
                           ); 
        
        $this->throwExceptionOnError($this->connection); 
      } 
      public function getEmployees() { 
        
        $stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename"); 
        $this->throwExceptionOnError(); 
        
        mysqli_stmt_execute($stmt); 
        $this->throwExceptionOnError(); 
          
        $rows = array(); 
          
        mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date, 
                    $row->first_name, $row->last_name, $row->gender, $row->hire_date); 
          
        while (mysqli_stmt_fetch($stmt)) { 
          $rows[] = $row; 
          $row = new stdClass(); 
          mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date, 
                      $row->first_name, $row->last_name, $row->gender, $row->hire_date); 
        } 
             
        mysqli_stmt_free_result($stmt); 
        mysqli_close($this->connection); 
        
        return $rows;  
      } 
      /** 
       * Utitity function to throw an exception if an error occurs 
       * while running a mysql command. 
       */ 
      private function throwExceptionOnError($link = null) { 
        if($link == null) { 
          $link = $this->connection; 
        } 
        if(mysqli_error($link)) { 
          $msg = mysqli_errno($link) . ": " . mysqli_error($link); 
          throw new Exception('MySQL Error - '. $msg); 
        }         
      } 
     
    } 
    ?>

    This PHP class contains functions that implement data service operations. Flash Builder introspects the service operations in the PHP class to create ActionScript classes in the client application. The client application accesses the data service using these ActionScript classes.

  3. Save EmployeeService.php at the following location:
    <Web Root>/PHPService/services/EmployeeService.php
    Note: Make sure that the filename corresponds to the name of the class implementing the PHP service.
  4. In EmployeeService.php, examine the code that calls the database.

    • Connecting to data:

      The code uses global variables and a constructor function that connects to the database server.

      Substitute your connection settings for the global variables.

    • Call the database:

      $stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename"); 
      mysqli_stmt_execute($stmt); 

      This code implements a basic PHP call to a database to return a result set. This call uses prepared statements available with the MySQLi extension. Prepares statements provide more security than a basic database query.

    • Return the data as an array of rows:

      $rows = array(); 
      mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date, 
                  $row->first_name, $row->last_name, $row->gender, $row->hire_date); 
      while (mysqli_stmt_fetch($stmt)) { 
          $rows[] = $row; 
      $row = new stdClass(); 
              mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date, 
              $row->first_name, $row->last_name, $row->gender, $row->hire_date); 
      } 
      return $rows; 

      Flex expects data returned by the operation to be an object or an array of objects. The PHP code that handles the returned result set iterates through the result, returning an array of objects. Each object in the array corresponds to a retrieved record from the database, containing values for each column in the record.

      The code uses bound results for the prepared statement. This call allows the values of the result to correctly be bound to expected values of the data.

    • Exception handling

      The code creates a utility function to catch exceptions.

(Optional) Test the PHP service

It is always a good idea to test a service before you access it from an application.

  1. Create a PHP script file, tester.php, that calls the service and displays the returned data.

    <pre> 
    <?php 
        include('EmployeeService.php'); 
        $o = new EmployeeService(); 
        var_dump($o->getemployees()); 
    ?> 
    </pre>
  2. Save tester.php in the same folder as EmployeeService.php, and call the service from a web browser.

    If the call is successful, tester dumps records from the database:

    array(999) { 
    [0]=> 
        object(stdClass)#4 (6) { 
            ["emp_no"]=> 
            string(5) "10002" 
            ["birth_date"]=> 
            string(10) "1964-06-02" 
            ["first_name"]=> 
            string(7) "Bezalel" 
            ["last_name"]=> 
            string(6) "Simmel" 
            ["gender"]=> 
            string(1) "F" 
            ["hire_date"]=> 
            string(10) "1985-11-21" 
        } 
    [1]=> 
        object(stdClass)#5 (6) { 
            ["emp_no"]=> 
            string(5) "10003" 
            ["birth_date"]=> 
            string(10) "1959-12-03" 
            ["first_name"]=> 
            string(5) "Parto" 
            ["last_name"]=> 
            string(7) "Bamford" 
            ["gender"]=> 
            string(1) "M" 
            ["hire_date"]=> 
            string(10) "1986-08-28" 
        } 
    [2]=> 
        object(stdClass)#6 (6) { 
            ["emp_no"]=> 
    . . .

    If there is an error in the service, PHP displays information to help locate the error.

    Warning:  mysqli_connect() [function.mysqli-connect]: (28000/1045): 
        Access denied for user 'admin'@'localhost' (using password: YES) in 
        C:\wamp2\www\PHP_Service\services\PHPservice.php on line 6 
     
    Access denied for user 'admin'@'localhost' (using password: YES)
You can also test a service after importing the service into Flash Builder. Use Test Operation, which is available from the Data/Service view.

Import the service into Flex and bind returned data to application components

The relationship between client code and server code in Flex differs from the traditional relationship in a server template.

In a traditional relationship, a server template mixes server code with client code. When the client queries a database, it dynamically embeds HTML code with returned data.

Flex, however, separates client code from server code. The remote service returns only data. Flex binds the returned data to user interface components in the client application.

  1. In Flash Builder, select File > New > Flex Project.

  2. Specify PHP_Service for the project name and set the Application Server Type to PHP.

    View full size graphic
    Specify project name and server type
    Note: If you forget to set the application server type when you create the project, you can later specify the server type from the Project Properties page.
  3. Click Next. Verify your PHP configuration and click Validate Configuration.

  4. For Output Folder, specify the PHPService folder you created previously.

    Flash Builder suggests a default location for the output folder. Use the location that already contains EmployeeService.php. Here is the location previously specified:

    <Web Root>/PHPService/
  5. Click Finish.

    The Flash Builder source editor opens to PHP_Service.mxml.

  6. Select Design to open the editor in Design mode. Add a DataGrid control to the application:

    The DataGrid component is available under Data Controls in the Components view. Drag the DataGrid control to the design area.

  7. From the context menu for the DataGrid, select Bind to Data.

  8. In the No Services Defined dialog, click Yes to connect to a service.

  9. In the New Flex Service wizard, select PHP. Click Next.

    Flash Builder provides multiple ways to connect to a data service. In this scenario, you first create the user interface. Then from a user interface component, you can connect to a service and specify the remote operation.
  10. Click Browse and navigate to the EmployeeService.php file you created previously.

    The path to the file is:

    <Web Root>/PHP_Service/services/EmployeeService.php

    Click Finish. Flash Builder prompts you to install or update the Zend Framework, if necessary.

    The Data Services View now displays the EmployeeService.

  11. From the DataGrid context menu, again select Bind to Data.

    The Bind to Data dialog opens with New Service Call selected.

    EmployeeService is the only service available in the Flex project.

    getEmployeess() is the only operation available in the service.

  12. In the Bind to Data dialog, select Configure Return Type to define the data type for returned data.

    Flex uses the return data type to access service operations. The EmployeeService service does not define the data type for returned data. Flash Builder uses client-side typing to define a custom data type for the returned data.

  13. In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.

  14. Specify Employee for the name of the type.

    The EmployeeService returns a complex data type representing a database record for an employee. The custom type Employee provides access to each field of the record.

    View the properties of the Employee data type returned by the service. Click Finish.

    When Flash Builder configures a return type, it accesses the database to create a value object. The properties of the custom data type are derived from the value object. You can view and modify the properties of the data type before proceeding.
  15. In the Bind to Data dialog, click OK.

    Flash Builder binds the data returned from the service call to the DataGrid component. It modifies the columns of the DataGrid, binding the value returned for each Employee property to a column in the DataGrid.

  16. Make sure the DataGrid is still selected. In the Properties view, click Configure Columns and then do the following steps:

    1. Select the hire_date column. Click Delete to delete the column.

    2. Similarly, delete all columns except emp_no, first_name, and last_name.

    3. Select the emp_no column. Click Up to move it to the first position.

    4. In the Header Text field, rename the emp_no column to ID.

    5. Similarly, rename the first_name and last_name columns.

    6. Click OK.

  17. With the DataGrid still selected, in the Properties view, specify False for the editable property.

  18. Select File > Save to save the application file. Then select Run > Run PHP_Service to run the application.

    The application runs in a web browser.