SlideShare ist ein Scribd-Unternehmen logo
1 von 50
Downloaden Sie, um offline zu lesen
Zend Framework
“at your service”
   Michelangelo van Dam
   Macq Electronique 2010, Brussels
WARNING

            Used Environment
                  PHP 5.3.2
            Zend Framework 1.10.4
                MySQL 5.1.32


Examples might not work on another environment
Michelangelo van Dam

• Independent Consultant
• Zend Certified Engineer (ZCE)
 - PHP 4 & PHP 5
 - Zend Framework
• Co-Founder of PHPBenelux
• Shepherd of “elephpant” herds
What is Zend Framework
      A loosly-coupled framework
      with a flexible architecture that
      lets you easily build modern
      web applications and web
      services
      Matthew Weier O’Phinney - Chief Architect Zend Framework
Why a service ?
•- opening up existing API
   internal applications
 - external applications
 - additional functionality
• support to more devices
• portability and flexibility
Important components
• - Zend_Soap
      Zend_Soap_Server
    - Zend_Soap_Client
    - Zend_Soap_Wsdl
•    Zend_Rest
    - Zend_Rest_Server
    - Zend_Rest_Client
•    Zend_XmlRpc
    - Zend_XmlRpc_Server
    - Zend_XmlRpc_Client
    - Zend_XmlRpc_Request
    - Zend_XmlRpc_Response
Example service
•- Time registration
     list time sheets
 -   add a new task
 -   edit an existing task
 -   delete an existing task
MVC approach
•- time module
     controllers (for displaying listing and forms)
 -   actions (for listing, adding, editing and deleting)
 -   models (for access to database)
 -   forms (for filtering, validation and rendering forms)
Common behavior
• all “logic” is put in the controller
• actions = API interface
•- downside
     not flexible towards other clients
 -   difficult to provide maintenance
 -   not reusable design
Time Module
              Time_IndexController
 indexAction                editAction
- lists registered tasks   - displays a form
- links to the form          - for adding task
  - for adding task          - for editing task
  - for editing task
  - for deleting task


 registerAction             deleteAction
- processes form data      - deletes task
  - validating data
  - storing data in db
API Design
•- moving logic
    out the controller
 - in an API class
• structures the application
• is better testable
• is better maintainable
Time API
                My_Api_Timesheet
 listTasks                  registerNewTask
- lists registered tasks   - for adding task




 editExistingTask           deleteExistingTask
- for modifying task       - deletes task
Simple ?
API output channels
 Web    Internal    SOAP




 XML    API        XMLRPC




 JSON     …         REST
Timesheet API
DocBlocks are important!
•- DocBlocks are very important !
     provide quality API documentation
 -   can be used as reference for the service !!!
Automated API docs
My_Api_Timesheet
<?php
class My_Api_Timesheet
{
}
listTasks
/**
  * List all tasks for a given user
  *
  * @param int $user
  * @param int $limit
  * @return array
  */
public function listTasks($user, $limit = null)
{
	 $array = array ();
	 $timesheet = new Time_Model_Timesheet();
	 if (null !== ($result = $timesheet->fetchAll(array (
	 	 'user_id = ?' => $user,
	 ), array ('date DESC', 'start_time ASC'), $limit))) {
	 	 foreach ($result as $entry) {
	 	 	 $array[] = $entry->toArray();
	 	 }
	 }
	 return $array;
}
registerNewTask
/**
 * Register a new task
 *
 * @param int $user The ID of the user
 * @param int $customer The ID of the customer
 * @param int $task The ID of the task
 * @param string $date A date formatted as YYYY-mm-dd
 * @param string $start The starting time as HH:mm:ss
 * @param string $end The ending time as HH:mm:ss
 * @param string $description A short description
 * @return bool TRUE if registration succeeded
 * @throws My_Api_Timesheet_Exception
 */
registerNewTask
public function registerNewTask(
        $user, $customer, $task, $date, $start, $end, $description)
{
	 $timesheet = new Time_Model_Timesheet();
	 $timesheet->setUserId($user)
	            ->setCustomerId($customer)
	            ->setTaskId($task)
	            ->setDate($date)
	            ->setStartTime($start)
	            ->setEndTime($end)
	            ->setDescription($description);
	 $validator = $this->_validate($timesheet);
	
	 if (false === $validator) {
	 	 require_once 'My/Api/Timesheet/Exception.php';
	 	 throw new My_Api_Timesheet_Exception('Invalid data provided');
	 }
	 $timesheet->save();
	
	 return true;
}
editExistingTask
/**
 * Modify an existing task
 *
 * @param int $id The ID of an existing Task
 * @param int $user The ID of the user
 * @param int $customer The ID of the customer
 * @param int $task The ID of the task
 * @param string $date A date formatted as YYYY-mm-dd
 * @param string $start The starting time as HH:mm:ss
 * @param string $end The ending time as HH:mm:ss
 * @param string $description A short description
 * @return bool TRUE if registration succeeded
 * @throws My_Api_Timesheet_Exception
 */
editExistingTask
public function editExistingTask(
                    $id, $user, $customer, $task, $date, $start, $end, $description)
{
	   $timesheet = new Time_Model_Timesheet();
	   $timesheet->setId($id)
	   	   	     ->setUserId($user)
	   	   	     ->setCustomerId($customer)
	   	   	     ->setTaskId($task)
	   	   	     ->setDate($date)
	   	   	     ->setStartTime($start)
	   	   	     ->setEndTime($end)
	   	   	     ->setDescription($description);
	   $validator = $this->_validate($timesheet);
	
	   if (false === $validator) {
	   	   require_once 'My/Api/Timesheet/Exception.php';
	   	   throw new My_Api_Timesheet_Exception('Invalid data provided');
	   }
	   $timesheet->save();
	
	   return true;
}
deleteExistingTask
/**
  * Removes an existing task
  *
  * @param int $id The ID of an existing Task
  * @param int $user The ID of the user
  * @return bool TRUE if registration succeeded
  */
public function deleteExistingTask($id, $user)
{
	    $timesheet = new Time_Model_Timesheet();
	    $timesheet->setId($id)
	    	   	     ->setUserId($user);
	    $validator = $this->_validate($timesheet);
	    if (false === $validator) {
	    	   require_once 'My/Api/Timesheet/Exception.php';
	    	   throw new My_Api_Timesheet_Exception('Invalid data provided');
	    }
	    $timesheet->delete(array (
	    	   'id = ?' => $timesheet->getId(),
	    	   'user_id = ?' => $timesheet->getUserId(),
	    ));
	
	    return true;
}
_validate
/**
  * Private validation method
  *
  * @param Time_Model_Timesheet $timesheet
  * @return bool TRUE if validated, FALSE if invalid
  */
private function _validate(Time_Model_Timesheet $timesheet)
{
	 $result = true;
	 $validator = new Time_Form_Register();
	
	 $customer = new Time_Model_Customer();
	 $task = new Time_Model_Task();
	 $validator->getElement('customer_id')->setMultiOptions($customer->toSelect());
	 $validator->getElement('task_id')->setMultiOptions($task->toSelect());
	
	 if (!$validator->isValid($timesheet->toArray())) {
	 	 $result = false;
	 }
	 return $result;
}
Zend_XmlRpc
XmlRpc Server
<?php
class Time_XmlRpcController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->_helper->layout()->disableLayout();
    	   $this->_helper->viewRenderer->setNoRender(true);
    	
    	   require_once 'My/Api/Timesheet.php';
        $server = new Zend_XmlRpc_Server();
        $server->setClass('My_Api_Timesheet');
        echo $server->handle();
    }
}
XmlRpc Client
<?php
class Time_XmlRpcClientController
      extends Zend_Controller_Action
{
    protected $_client;

    public function init()
    {
        $this->_helper->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
        $this->_client = new Zend_XmlRpc_Client(
            'http://www.demo.local/Time/XmlRpc');
    }
…
}
XmlRpc Client
public function newAction()
{
    	
    $client = $this->_client;
    	
    $request = new Zend_XmlRpc_Request();
    	
    $request->setMethod('registerNewTask');
    	
    $request->setParams(array (
    	
    	    2,	 	    	   	    	   // user ID
    	
    	    3,	 	    	   	    	   // customer ID
    	
    	    3,	 	    	   	    	   // task ID
    	
    	    '2010-03-28',	
                      	    // date
    	
    	    '18:00:00',	 	    	   // start time
    	
    	    '23:30:00',	 	    	   // end time
    	
    	    'Demo XmlRpc add',	   // description
    	
    ));
    	
    $result = null;
    	
    $errors = array ();
    	
    try {
    	
    	    $client->doRequest($request);
    	
    	    $result = $client->getLastResponse()->getReturnValue();
    	 catch (Zend_XmlRpc_Client_FaultException $e) {
    }
    	
    	    $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	 catch (Zend_XmlRpc_Client_HttpException $e) {
    }
    	
    	    $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	 catch (My_Api_Timesheet_Exception $e) {
    }
    	
    	    $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	
    }
}
XmlRpc Client
public function editAction()
{
    	$client = $this->_client;
    	$request = new Zend_XmlRpc_Request();
    	$request->setMethod('editExistingTask');
    	$request->setParams(array (
    		    5,	 	     	    	    	    // ID
    		    2,	 	     	    	    	    // user ID
    		    3,	 	     	    	    	    // customer ID
    		    4,	 	     	    	    	    // task ID
    		    '2010-03-28',	 	    // date
    		    '18:00:00',	 	      	    // start time
    		    '23:30:00',	 	      	    // end time
    		    'Demo XmlRpc add',	 // description
    	));
    	$result = null;
    	$errors = array ();
    	try {
    		    $client->doRequest($request);
    		    $result = $client->getLastResponse()->getReturnValue();
    	} catch (Zend_XmlRpc_Client_FaultException $e) {
    		    $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	} catch (Zend_XmlRpc_Client_HttpException $e) {
    		    $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	} catch (My_Api_Timesheet_Exception $e) {
    		    $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	}
}
XmlRpc Client
public function deleteAction()
{
    	
    $client = $this->_client;
    	
    $request = new Zend_XmlRpc_Request();
    	
    $request->setMethod('deleteExistingTask');
    	
    $request->setParams(array (
    	
    	    6,	 	    	   	   	    // ID
    	
    	    2,	 	    	   	   	    // user ID
    	
    ));
    	
    $result = null;
    	
    $errors = array ();
    	
    try {
    	
    	    $client->doRequest($request);
    	
    	    $result = $client->getLastResponse()->getReturnValue();
    	
    	    if ($client->getLastResponse()->isFault()) {
    	
    	    	   $result = $client->getLastResponse()->getFault();
    	
    	    }
    	 catch (Zend_XmlRpc_Client_FaultException $e) {
    }
    	
    	    $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	 catch (Zend_XmlRpc_Client_HttpException $e) {
    }
    	
    	    $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	 catch (My_Api_Timesheet_Exception $e) {
    }
    	
    	    $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}";
    	
    }
}
Zend_Soap
SOAP Server
<?php
class Time_SoapController extends Zend_Controller_Action
{
    public function indexAction()
    {
    	$this->_helper->layout()->disableLayout();
    	$this->_helper->viewRenderer->setNoRender(true);
    	
    	$options = array ();
    	$server = new Zend_Soap_AutoDiscover();
    	$server->setClass('My_Api_Timesheet');
    	$server->handle();
    }
}
SOAP Client
<?php
class Time_SoapClientController extends Zend_Controller_Action
{
	 protected $_client;
	
	 public function init()
	 {
	 	 $this->_helper->layout()->disableLayout();
    	 $this->_helper->viewRenderer->setNoRender(true);
    	 $this->_client = new Zend_Soap_Client(
    	 	 'http://www.demo.local/Time/soap?wsdl', array ());
	 }

     public function indexAction()
     {
        $result = $this->_client->listTasks(2, 2);
	   	 $this->getResponse()->setHeader('Content-Type', 'text/xml; Charset=UTF-8');
     	 echo $this->_client->getLastResponse();
     }
…
SOAP Client
public function addAction()
    {
    	 Zend_Debug::dump($this->_client->registerNewTask(
    	 	 2, 2, 3, '2010-03-30', '18:00:00',
         '23:30:00','Setting up SOAP'));
    }
    public function editAction()
    {
    	 Zend_Debug::dump($this->_client->editExistingTask(
    	 	 7, 2, 2, 3, '2010-03-30', '18:00:00',
         '23:30:00','Testing SOAP'));
    }
    public function deleteAction()
    {
    	 Zend_Debug::dump($this->_client->deleteExistingTask(7, 2));
    }
}
Zend_Rest
REST Server
<?php
class Time_RestController extends Zend_Controller_Action
{
    public function indexAction()
    {
    	$this->_helper->layout()->disableLayout();
    	$this->_helper->viewRenderer->setNoRender(true);
    	
    	$server = new Zend_Rest_Server();
    	$server->setClass('My_Api_Timesheet');
    	$server->handle();
    }
}
REST Client
<?php

class Time_RestClientController extends Zend_Controller_Action
{
	 protected $_client;
	
    public function init()
    {
    	 $this->_helper->layout()->disableLayout();
    	 $this->_helper->viewRenderer->setNoRender(true);
    	 $this->_client = new Zend_Rest_Client('http://www.demo.local/Time/rest');
    }

     public function indexAction()
     {
	   	 $this->_client->listTasks(2);
     	 Zend_Debug::dump($this->_client->get());
     }
}
Patterns ???
Conclusion

moving functionality out the controller
          into a library API
                   =
              saves time

1 api = XmlRpc + SOAP + REST + …
Recommended reading
    Web Services Essentials
    Ethan Cerami

    O’Reilly



    Programming Web Services with XML-RPC
    Simon St. Laurent, Joe Johnston, Edd Dumbill,
    Dave Winer

    O’Reilly
Recommended reading
    RESTful Web Services
    Leonard Richardson, Sam Ruby

    O’Reilly



    Programming Web Services with XML-RPC
    James Snell, Doug Tidwell, Pavel Kulchenko

    O’Reilly
We need you help !!!
Feedback is important
•- find a bug ?
    test it
 - report it
 - send a patch/fix
• need a non-existing component
 - submit proposal
• like Zend Framework
 - blog about it
 - talk about it
• translations
ZF Bug hunt days
   Zend Framework Bughuntdays
     every 3rd Thursday and Friday of the month
          http://framework.zend.com/issues
          IRC (irc.freenode.net) #zftalk.dev

                        prizes:
    recognition and appreciation of the community
Free subscription for 1 year on php|Architect magazine
                Zend Framework t-shirt
ZF issue tracker
• When: June 10 - 12 2010
• Where: Amsterdam RAI
• Tickets: http://phpconference.nl
 • Early bird: ends April 30, 2010 (Queen’s Day)
PHP
                              BENELUX



• annual event
• improve code coverage
• test php core source code
• improve quality of PHP
PHP
                           BENELUX


• When: May 29, 2010
• Where: <to-be-defined>
• Updates:
 • web: http://www.phpbenelux.eu
 • twitter: @phpbenelux
Thank you !


         Slides on Slideshare
http://www.slideshare.net/group/macqel

      Give feedback on Joind.in
         http://joind.in/1263

Weitere ähnliche Inhalte

Was ist angesagt?

The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
When cqrs meets event sourcing
When cqrs meets event sourcingWhen cqrs meets event sourcing
When cqrs meets event sourcingManel Sellés
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介Jace Ju
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome TownRoss Tuck
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2eugenio pombi
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationSamuel ROZE
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form componentSamuel ROZE
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsClinton Dreisbach
 
Introduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingIntroduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingSamuel ROZE
 

Was ist angesagt? (20)

The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
When cqrs meets event sourcing
When cqrs meets event sourcingWhen cqrs meets event sourcing
When cqrs meets event sourcing
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
Introduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingIntroduction to CQRS and Event Sourcing
Introduction to CQRS and Event Sourcing
 

Ähnlich wie Introduction to Zend Framework web services

WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersKacper Gunia
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperGary Hockin
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Shinya Ohyanagi
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection apiMatthieu Aubry
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your CodeAbbas Ali
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 

Ähnlich wie Introduction to Zend Framework web services (20)

Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 Developer
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 

Mehr von Michelangelo van Dam

GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultGDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultMichelangelo van Dam
 
Moving from app services to azure functions
Moving from app services to azure functionsMoving from app services to azure functions
Moving from app services to azure functionsMichelangelo van Dam
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyGeneral Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyMichelangelo van Dam
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageLeveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageMichelangelo van Dam
 
Open source for a successful business
Open source for a successful businessOpen source for a successful business
Open source for a successful businessMichelangelo van Dam
 
Decouple your framework now, thank me later
Decouple your framework now, thank me laterDecouple your framework now, thank me later
Decouple your framework now, thank me laterMichelangelo van Dam
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesDeploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesMichelangelo van Dam
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heavenAzure and OSS, a match made in heaven
Azure and OSS, a match made in heavenMichelangelo van Dam
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your projectMichelangelo van Dam
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
Easily extend your existing php app with an api
Easily extend your existing php app with an apiEasily extend your existing php app with an api
Easily extend your existing php app with an apiMichelangelo van Dam
 

Mehr von Michelangelo van Dam (20)

GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultGDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and default
 
Moving from app services to azure functions
Moving from app services to azure functionsMoving from app services to azure functions
Moving from app services to azure functions
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
 
DevOps or DevSecOps
DevOps or DevSecOpsDevOps or DevSecOps
DevOps or DevSecOps
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
 
Continuous deployment 2.0
Continuous deployment 2.0Continuous deployment 2.0
Continuous deployment 2.0
 
Let your tests drive your code
Let your tests drive your codeLet your tests drive your code
Let your tests drive your code
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyGeneral Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's story
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageLeveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantage
 
The road to php 7.1
The road to php 7.1The road to php 7.1
The road to php 7.1
 
Open source for a successful business
Open source for a successful businessOpen source for a successful business
Open source for a successful business
 
Decouple your framework now, thank me later
Decouple your framework now, thank me laterDecouple your framework now, thank me later
Decouple your framework now, thank me later
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesDeploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutes
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heavenAzure and OSS, a match made in heaven
Azure and OSS, a match made in heaven
 
Getting hands dirty with php7
Getting hands dirty with php7Getting hands dirty with php7
Getting hands dirty with php7
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
 
The Continuous PHP Pipeline
The Continuous PHP PipelineThe Continuous PHP Pipeline
The Continuous PHP Pipeline
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Easily extend your existing php app with an api
Easily extend your existing php app with an apiEasily extend your existing php app with an api
Easily extend your existing php app with an api
 

Kürzlich hochgeladen

Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 

Kürzlich hochgeladen (20)

Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 

Introduction to Zend Framework web services

  • 1. Zend Framework “at your service” Michelangelo van Dam Macq Electronique 2010, Brussels
  • 2. WARNING Used Environment PHP 5.3.2 Zend Framework 1.10.4 MySQL 5.1.32 Examples might not work on another environment
  • 3. Michelangelo van Dam • Independent Consultant • Zend Certified Engineer (ZCE) - PHP 4 & PHP 5 - Zend Framework • Co-Founder of PHPBenelux • Shepherd of “elephpant” herds
  • 4. What is Zend Framework A loosly-coupled framework with a flexible architecture that lets you easily build modern web applications and web services Matthew Weier O’Phinney - Chief Architect Zend Framework
  • 5. Why a service ? •- opening up existing API internal applications - external applications - additional functionality • support to more devices • portability and flexibility
  • 6. Important components • - Zend_Soap Zend_Soap_Server - Zend_Soap_Client - Zend_Soap_Wsdl • Zend_Rest - Zend_Rest_Server - Zend_Rest_Client • Zend_XmlRpc - Zend_XmlRpc_Server - Zend_XmlRpc_Client - Zend_XmlRpc_Request - Zend_XmlRpc_Response
  • 7. Example service •- Time registration list time sheets - add a new task - edit an existing task - delete an existing task
  • 8. MVC approach •- time module controllers (for displaying listing and forms) - actions (for listing, adding, editing and deleting) - models (for access to database) - forms (for filtering, validation and rendering forms)
  • 9. Common behavior • all “logic” is put in the controller • actions = API interface •- downside not flexible towards other clients - difficult to provide maintenance - not reusable design
  • 10. Time Module Time_IndexController indexAction editAction - lists registered tasks - displays a form - links to the form - for adding task - for adding task - for editing task - for editing task - for deleting task registerAction deleteAction - processes form data - deletes task - validating data - storing data in db
  • 11. API Design •- moving logic out the controller - in an API class • structures the application • is better testable • is better maintainable
  • 12. Time API My_Api_Timesheet listTasks registerNewTask - lists registered tasks - for adding task editExistingTask deleteExistingTask - for modifying task - deletes task
  • 14. API output channels Web Internal SOAP XML API XMLRPC JSON … REST
  • 16. DocBlocks are important! •- DocBlocks are very important ! provide quality API documentation - can be used as reference for the service !!!
  • 19. listTasks /** * List all tasks for a given user * * @param int $user * @param int $limit * @return array */ public function listTasks($user, $limit = null) { $array = array (); $timesheet = new Time_Model_Timesheet(); if (null !== ($result = $timesheet->fetchAll(array ( 'user_id = ?' => $user, ), array ('date DESC', 'start_time ASC'), $limit))) { foreach ($result as $entry) { $array[] = $entry->toArray(); } } return $array; }
  • 20. registerNewTask /** * Register a new task * * @param int $user The ID of the user * @param int $customer The ID of the customer * @param int $task The ID of the task * @param string $date A date formatted as YYYY-mm-dd * @param string $start The starting time as HH:mm:ss * @param string $end The ending time as HH:mm:ss * @param string $description A short description * @return bool TRUE if registration succeeded * @throws My_Api_Timesheet_Exception */
  • 21. registerNewTask public function registerNewTask( $user, $customer, $task, $date, $start, $end, $description) { $timesheet = new Time_Model_Timesheet(); $timesheet->setUserId($user) ->setCustomerId($customer) ->setTaskId($task) ->setDate($date) ->setStartTime($start) ->setEndTime($end) ->setDescription($description); $validator = $this->_validate($timesheet); if (false === $validator) { require_once 'My/Api/Timesheet/Exception.php'; throw new My_Api_Timesheet_Exception('Invalid data provided'); } $timesheet->save(); return true; }
  • 22. editExistingTask /** * Modify an existing task * * @param int $id The ID of an existing Task * @param int $user The ID of the user * @param int $customer The ID of the customer * @param int $task The ID of the task * @param string $date A date formatted as YYYY-mm-dd * @param string $start The starting time as HH:mm:ss * @param string $end The ending time as HH:mm:ss * @param string $description A short description * @return bool TRUE if registration succeeded * @throws My_Api_Timesheet_Exception */
  • 23. editExistingTask public function editExistingTask( $id, $user, $customer, $task, $date, $start, $end, $description) { $timesheet = new Time_Model_Timesheet(); $timesheet->setId($id) ->setUserId($user) ->setCustomerId($customer) ->setTaskId($task) ->setDate($date) ->setStartTime($start) ->setEndTime($end) ->setDescription($description); $validator = $this->_validate($timesheet); if (false === $validator) { require_once 'My/Api/Timesheet/Exception.php'; throw new My_Api_Timesheet_Exception('Invalid data provided'); } $timesheet->save(); return true; }
  • 24. deleteExistingTask /** * Removes an existing task * * @param int $id The ID of an existing Task * @param int $user The ID of the user * @return bool TRUE if registration succeeded */ public function deleteExistingTask($id, $user) { $timesheet = new Time_Model_Timesheet(); $timesheet->setId($id) ->setUserId($user); $validator = $this->_validate($timesheet); if (false === $validator) { require_once 'My/Api/Timesheet/Exception.php'; throw new My_Api_Timesheet_Exception('Invalid data provided'); } $timesheet->delete(array ( 'id = ?' => $timesheet->getId(), 'user_id = ?' => $timesheet->getUserId(), )); return true; }
  • 25. _validate /** * Private validation method * * @param Time_Model_Timesheet $timesheet * @return bool TRUE if validated, FALSE if invalid */ private function _validate(Time_Model_Timesheet $timesheet) { $result = true; $validator = new Time_Form_Register(); $customer = new Time_Model_Customer(); $task = new Time_Model_Task(); $validator->getElement('customer_id')->setMultiOptions($customer->toSelect()); $validator->getElement('task_id')->setMultiOptions($task->toSelect()); if (!$validator->isValid($timesheet->toArray())) { $result = false; } return $result; }
  • 27. XmlRpc Server <?php class Time_XmlRpcController extends Zend_Controller_Action { public function indexAction() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); require_once 'My/Api/Timesheet.php'; $server = new Zend_XmlRpc_Server(); $server->setClass('My_Api_Timesheet'); echo $server->handle(); } }
  • 28. XmlRpc Client <?php class Time_XmlRpcClientController extends Zend_Controller_Action { protected $_client; public function init() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $this->_client = new Zend_XmlRpc_Client( 'http://www.demo.local/Time/XmlRpc'); } … }
  • 29. XmlRpc Client public function newAction() { $client = $this->_client; $request = new Zend_XmlRpc_Request(); $request->setMethod('registerNewTask'); $request->setParams(array ( 2, // user ID 3, // customer ID 3, // task ID '2010-03-28', // date '18:00:00', // start time '23:30:00', // end time 'Demo XmlRpc add', // description )); $result = null; $errors = array (); try { $client->doRequest($request); $result = $client->getLastResponse()->getReturnValue(); catch (Zend_XmlRpc_Client_FaultException $e) { } $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}"; catch (Zend_XmlRpc_Client_HttpException $e) { } $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}"; catch (My_Api_Timesheet_Exception $e) { } $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}"; } }
  • 30. XmlRpc Client public function editAction() { $client = $this->_client; $request = new Zend_XmlRpc_Request(); $request->setMethod('editExistingTask'); $request->setParams(array ( 5, // ID 2, // user ID 3, // customer ID 4, // task ID '2010-03-28', // date '18:00:00', // start time '23:30:00', // end time 'Demo XmlRpc add', // description )); $result = null; $errors = array (); try { $client->doRequest($request); $result = $client->getLastResponse()->getReturnValue(); } catch (Zend_XmlRpc_Client_FaultException $e) { $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (Zend_XmlRpc_Client_HttpException $e) { $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (My_Api_Timesheet_Exception $e) { $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}"; } }
  • 31. XmlRpc Client public function deleteAction() { $client = $this->_client; $request = new Zend_XmlRpc_Request(); $request->setMethod('deleteExistingTask'); $request->setParams(array ( 6, // ID 2, // user ID )); $result = null; $errors = array (); try { $client->doRequest($request); $result = $client->getLastResponse()->getReturnValue(); if ($client->getLastResponse()->isFault()) { $result = $client->getLastResponse()->getFault(); } catch (Zend_XmlRpc_Client_FaultException $e) { } $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}"; catch (Zend_XmlRpc_Client_HttpException $e) { } $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}"; catch (My_Api_Timesheet_Exception $e) { } $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}"; } }
  • 33. SOAP Server <?php class Time_SoapController extends Zend_Controller_Action { public function indexAction() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $options = array (); $server = new Zend_Soap_AutoDiscover(); $server->setClass('My_Api_Timesheet'); $server->handle(); } }
  • 34. SOAP Client <?php class Time_SoapClientController extends Zend_Controller_Action { protected $_client; public function init() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $this->_client = new Zend_Soap_Client( 'http://www.demo.local/Time/soap?wsdl', array ()); } public function indexAction() { $result = $this->_client->listTasks(2, 2); $this->getResponse()->setHeader('Content-Type', 'text/xml; Charset=UTF-8'); echo $this->_client->getLastResponse(); } …
  • 35. SOAP Client public function addAction() { Zend_Debug::dump($this->_client->registerNewTask( 2, 2, 3, '2010-03-30', '18:00:00', '23:30:00','Setting up SOAP')); } public function editAction() { Zend_Debug::dump($this->_client->editExistingTask( 7, 2, 2, 3, '2010-03-30', '18:00:00', '23:30:00','Testing SOAP')); } public function deleteAction() { Zend_Debug::dump($this->_client->deleteExistingTask(7, 2)); } }
  • 37. REST Server <?php class Time_RestController extends Zend_Controller_Action { public function indexAction() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $server = new Zend_Rest_Server(); $server->setClass('My_Api_Timesheet'); $server->handle(); } }
  • 38. REST Client <?php class Time_RestClientController extends Zend_Controller_Action { protected $_client; public function init() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $this->_client = new Zend_Rest_Client('http://www.demo.local/Time/rest'); } public function indexAction() { $this->_client->listTasks(2); Zend_Debug::dump($this->_client->get()); } }
  • 40. Conclusion moving functionality out the controller into a library API = saves time 1 api = XmlRpc + SOAP + REST + …
  • 41. Recommended reading Web Services Essentials Ethan Cerami O’Reilly Programming Web Services with XML-RPC Simon St. Laurent, Joe Johnston, Edd Dumbill, Dave Winer O’Reilly
  • 42. Recommended reading RESTful Web Services Leonard Richardson, Sam Ruby O’Reilly Programming Web Services with XML-RPC James Snell, Doug Tidwell, Pavel Kulchenko O’Reilly
  • 43. We need you help !!!
  • 44. Feedback is important •- find a bug ? test it - report it - send a patch/fix • need a non-existing component - submit proposal • like Zend Framework - blog about it - talk about it • translations
  • 45. ZF Bug hunt days Zend Framework Bughuntdays every 3rd Thursday and Friday of the month http://framework.zend.com/issues IRC (irc.freenode.net) #zftalk.dev prizes: recognition and appreciation of the community Free subscription for 1 year on php|Architect magazine Zend Framework t-shirt
  • 47. • When: June 10 - 12 2010 • Where: Amsterdam RAI • Tickets: http://phpconference.nl • Early bird: ends April 30, 2010 (Queen’s Day)
  • 48. PHP BENELUX • annual event • improve code coverage • test php core source code • improve quality of PHP
  • 49. PHP BENELUX • When: May 29, 2010 • Where: <to-be-defined> • Updates: • web: http://www.phpbenelux.eu • twitter: @phpbenelux
  • 50. Thank you ! Slides on Slideshare http://www.slideshare.net/group/macqel Give feedback on Joind.in http://joind.in/1263