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 will walk you through setting up an employee list application that demonstrates some of the programming principles for Project Zero using PHP.

Introduction

The PHP Employee Demo uses RESTful resources to demonstrates many of Zero's capabilities. 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

Eclipse instructions

Create a new Example Project

If you have not already obtained the Zero Examples plugin you can do so by following here. Next go to File > New > Example.... Select the Project Zero Example Projects wizard and press Next.

zeroExampleWizard.png
Available Example Project Wizards

Check the PHP version of Employee Demo example project and press Finish.

PHPEmployeeDemoProj.png
Example projects for Project Zero

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

Now expand the project entry to see all the included files.

DemoProjectFiles.png
Contents of PHP Demo Project

Running the example

  • Resolve dependencies from remote repositories if they are not already cached locally.
    • Right-click phpemployee.demo project
    • Zero Tools > Resolve

  • The phpemployee.demo application will set 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.

  • Start the application
    • Right-click on the application and choose "Run As > Project Zero Application"

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 provides the graphical interface, mostly through use of Dojo Filtering 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 only be accessed through the four basic http requests (GET, POST, PUT, DELETE).

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

  • listEmployees() binds a GET request to /resources/employees where the return value is loaded into the employee table, empTable,
  • addEmployee() binds a POST request to /resources/employees. On return the add employee form is removed and the table is updated.
  • deleteEmployee() binds a DELETE request to /resources/employees/${selected_employee}. On return the table is updated.
  • editEmployee() binds 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 saving the following script as createDivisions.sql and running it with the derby tool ij.

connect 'jdbc:derby://localhost:1527/db/employeeDB;create=true';
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');

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.

By including the HTTP-method handler script, zero.php, we can create a class in collection.php using the naming convention [ResourceName](Collection|Item). In our case this means that the class needs to be named DivisionsCollection.

The entire divisions collection should be responsible for two actions, creating a new division and listing all divisions. This will be represented by the POST and GET calls respectively. The resulting collection.php should look something like the following:

<?php

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

Accessing the resource

Now we will modify the index.html to access our new resource.

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.html. 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. Your resulting index.html should look something like the image below, also see attached index.html 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 item.php for divisions and the edit and delete buttons 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.

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 35.4 K 27 Jun 2007 - 14:36 gimballock  
png divisionsTable.png props, move 27.5 K 12 Jul 2007 - 21:48 gimballock  
html index.html props, move 10.0 K 12 Jul 2007 - 21:46 gimballock  
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  
r17 - 26 Oct 2007 - 19:23:50 - madhu
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site