Broadcast on Broadcast off
The Documentation for Project Zero has moved. Please update your bookmarks to: http://www.projectzero.org/documentation/
Table of
Contents...
Hide
 

A simple PHP Zero tutorial

This simple tutorial, the PHP employee demo, sets up an employee list application that demonstrates some of the programming principles for Project Zero using PHP. The PHP Employee Demo uses RESTful resources to demonstrates many of the capabilities of Project Zero. It provides an interface for managing employee data, including listing, creating, editing and deleting employee records. Notable features demonstrated here include:

  • Automatic resource handling
  • PHP scripting
  • JSON APIs and rendering
  • Data access
  • Client programming with Dojo

The following sections of this article step through the process of creating the employee demo with PHP using Eclipse.

Creating a new example project

If you have not already obtained the Project Zero examples plug-in you can do so using the following steps:

  1. Go to the Project Zero Downloads page and select Eclipse.
  2. Click File > New > Example....
  3. Select the Project Zero Example Projects wizard.
  4. Click Next.
  5. zeroExampleWizard.png
    Available Example Project Wizards

  6. Select the PHP version of Employee Demo example project and click Finish.

    PHPEmployeeDemoProject.png
    Example projects for Project Zero

    The phpemployee.demo project should now be added to the Project Explorer panel in the Eclipse main window.

  7. Expand the project entry to see all the included files.

    expanded_project.jpg
    Contents of PHP Demo Project

Running the example

To run the example, use the following steps:

  1. Right-click the application and choose Run As > Project Zero Application to start the application. The phpemployee.demo application sets up a database and tables with some initial values when the application is started. The application uses Embedded Derby and a startup handler to do this.
  2. You can view the application at this location: http://localhost:8080/

    PHPDemoOutput.png
    Initial output of PHP Demo

Understanding the flow

The employee demo lists the employees from a table in the database and allows users to add, edit, modify or delete an employee. The welcome page displayed by the web browser is included in public/index.html. The public directory in the application is the effective document root of the application. Any index.html or index.php files under the public folder are invoked by default when the URL maps to the directory. So for instance the request for http://localhost:8080/ maps to the index.html in the public folder of the application.

The employee demo displays a table of employees and four buttons to modify the employees. These buttons correspond to the JavaScript handlers (listEmployees, addEmployee, deleteEmployee, editEmployee) which in turn place requests to /resources/employees/ which is a Zero RESTful resource. The Dojo library is used in this application for the AJAX interactions and there is a custom Dojo widget, my.widget.Table that renders the table.

Resource Handling

Each of the button handlers bind their associated action to a URI beginning with /resources/employees/ which gets mapped to phpemployee.demo/app/resources/employees.php. In general Zero maps all URI's of the form /resources/some.resource to ${your.app}/app/resources/some.resource.php. Resources of this form are referred to as RESTful because they contain no local context or state information and can be accessed through the four basic http methods (GET, POST, PUT, DELETE).

In our demo the RESTful resources are used for the following:

  • listEmployees() makes a GET request to /resources/employees where the return value is loaded into the employee table, empTable,
  • addEmployee() makes a POST request to /resources/employees. On return the add employee form is removed and the table is updated.
  • deleteEmployee() makes a DELETE request to /resources/employees/${selected_employee}. On return the table is updated.
  • editEmployee() makes a PUT request to /resources/employees/${selected_employee}. On return the edit employee form is removed and the table is refreshed.

Note: Since many web servers and proxy servers filter out DELETE and PUT requests, ZERO uses a POST request with an additional "X-Method-Override" header to avoid problems.

The /app/resources/employees.php script contains a class called Employees. By convention in Project Zero, a request for a resource is dispatched to one of a well known list of functions. For the single entity case, the entity identifier is saved in the Global Context as a request parameter "/request/params/${resource}Id". For the list above, the key in the Global Context will be "/request/params/employeesId" and the ${selected_employee} part will be replaced by a real entity id when running the application. So, a GET request with the URL /resources/employees/JerryCuomo would set the key "/request/params/employeesId" in the Global Context to "JerryCuomo".

The way to implement a resource handler is demonstrated by employee.php. It implements the employee resource using a PHP class called Employee with onList(), onCreate(), onUpdate(), onRetrieve() and onDelete() functions.

Extending the Example

To better solidify these concepts we will extend the example by adding division information for each employee.

Modify the Database

We need to add a new divisions table to the Derby database, employeeDB, then put a few entries into it. This can be done by appending the following snippet of sql to the file setup_db.sql in the application's root directory.

CREATE TABLE divisions (
   name varchar(32) NOT NULL,
   description varchar(64) NOT NULL,
   PRIMARY KEY (name)
);

insert into divisions values ('division1', 'First Division');
insert into divisions values ('division2', 'Second Division');

Now stop your application and delete the directory db/employee_db in the application root (to delete the database). When you restart your application, the tables will get created anew in this directory.

Creating a new resource

To expose the collection of divisions in the database to the rest of our web application we will create a new RESTful resource named divisions.

First create a new script in /app/resources/ called divisions.php. Inside that script you will create a class called Divisions.

The divisions resource should be responsible for two actions, creating a new division and listing all divisions. This will be represented by the onCreate() and onList() methods respectively. The resulting divisions.php should look something like the following:

<?php

class Divisions {
        
        function onList() {
                $dataManager = dataManager('employee_db');
                $divisions = dataExec($dataManager, "SELECT * FROM divisions");
                zput('/request/headers/out/Content-Type', 'text/json');
                echo json_encode($divisions);		
        }
        
        function onCreate() {
                $division = json_decode($HTTP_RAW_POST_DATA);
                $dataManager = dataManager('employee_db');
                $result = dataExec($dataManager, "INSERT INTO divisions (name, description) ". 
                "VALUES (?, ?)", array($division['name'], $division['description']));
                
                if ($result == 1) {
                        $locationUri = get('/request/path') . "/" . $division["name"];
                        zput('/request/headers/out/Location', $locationUri);
                        zput('/request/status', 204);
                } else { 
                        zput('/request/status', 400);
                }
        }
}
?>

Accessing the resource

To access the new resource, modify the index.php file.

Since we have exposed two new features which are similar to existing features (adding and listing employees) we can mimic existing code to more easily implement our new functionality.

First note the table near the bottom of index.php. Directly below that are the four buttons. We want a new table for divisions below the existing buttons. After the table is created we will need two buttons, List Divisions and Add Division. These buttons will execute listDivisions() and addDivision().

divisionsTable.png
HTML for Divisions table and related buttons

Below this you can find a number of forms hidden inside div tags, note the style="display:none". We will need to create a hidden form for entering new divisions. This form can be based off of the add employee form. The form's Submit and Cancel buttons should call addDivision() and removeDivisionForm() respectively.

newDivisionForm.png
HTML for "Add Division" form

The JavaScript functions are easily adapted from the employee counterparts. Also see attached index.php.txt at the bottom of this page.

NewJSFunctions.png
New JavaScript functions for "divisions" feature (collapsed)

From here it is left as an exercise to the reader to implement the edit and delete buttons for divisions in the main page. Adventurous readers may attempt to unify the two dojo tables into one.

Hint: Start by adding a foreign key to the employee table. Another Hint: Edit should have an equivalent onUpdate() method and Delete should have an equivalent onDelete() method defined in divisions.php.

PHPDemoOutput1.png
PHP Employee Demo with divisions added

  Attachment Action Size Date Who Comment
png DemoProjectFiles.png props, move 63.7 K 27 Jun 2007 - 14:47 gimballock  
png NewJSFunctions.png props, move 19.7 K 12 Jul 2007 - 21:48 gimballock  
png PHPDemoOutput.png props, move 29.0 K 27 Jun 2007 - 19:06 gimballock  
png PHPDemoOutput1.png props, move 41.9 K 28 Jun 2007 - 20:45 gimballock  
png PHPEmployeeDemoProj.png props, move 19.2 K 13 Dec 2007 - 22:34 madhu  
png PHPEmployeeDemoProject.png props, move 19.2 K 13 Dec 2007 - 22:38 madhu  
png divisionsTable.png props, move 27.5 K 12 Jul 2007 - 21:48 gimballock  
jpg expanded_project.jpg props, move 84.3 K 13 Dec 2007 - 22:40 madhu  
html index.html props, move 10.0 K 12 Jul 2007 - 21:46 gimballock  
txt index.php.txt props, move 10.5 K 14 Dec 2007 - 20:53 madhu  
png newDivisionForm.png props, move 27.8 K 12 Jul 2007 - 21:48 gimballock  
png zeroExampleWizard.png props, move 31.9 K 27 Jun 2007 - 14:31 gimballock  
r21 - 14 Dec 2007 - 20:55:15 - madhu
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site