the state of soap in php

112
THE STATE OF SOAP IN PHP

Upload: david-zuelke

Post on 15-Jan-2015

7.511 views

Category:

Technology


4 download

DESCRIPTION

Presentation at PHP Barcelona 2009

TRANSCRIPT

Page 1: The State of SOAP in PHP

THE STATE OF SOAP IN PHP

Page 2: The State of SOAP in PHP

David Zülke

Page 3: The State of SOAP in PHP

David Zuelke

Page 4: The State of SOAP in PHP
Page 5: The State of SOAP in PHP

apologies

Page 6: The State of SOAP in PHP
Page 9: The State of SOAP in PHP

back from

Page 10: The State of SOAP in PHP

ZendCon

Page 11: The State of SOAP in PHP

Page 12: The State of SOAP in PHP

Page 13: The State of SOAP in PHP

http://en.wikipedia.org/wiki/File:München_Panorama.JPG

Page 14: The State of SOAP in PHP

Founder

Page 16: The State of SOAP in PHP

Lead Developer

Page 18: The State of SOAP in PHP

@dzuelke

Page 19: The State of SOAP in PHP

WHAT IS SOAP?And How Did It All Start?

Page 20: The State of SOAP in PHP

original plan

Page 21: The State of SOAP in PHP

talk

Page 22: The State of SOAP in PHP
Page 23: The State of SOAP in PHP

dis is srs bsns

Page 24: The State of SOAP in PHP

make

Page 25: The State of SOAP in PHP

http://flic.kr/kevinsteele/230997861/

KittY NotIncluded

Page 26: The State of SOAP in PHP
Page 27: The State of SOAP in PHP

however

Page 28: The State of SOAP in PHP

http://en.wikipedia.org/wiki/File:Flughafenkontrolle.jpg

Page 29: The State of SOAP in PHP

risk

Page 30: The State of SOAP in PHP
Page 31: The State of SOAP in PHP

SHOOT MEIN THE FACE

Page 32: The State of SOAP in PHP

WHAT IS SOAP?And How Did It All Start?

Page 33: The State of SOAP in PHP

Data Exchange Protocol

Page 34: The State of SOAP in PHP

XML-based

Page 35: The State of SOAP in PHP

language independent

Page 36: The State of SOAP in PHP

platform independent

Page 37: The State of SOAP in PHP

typically used for RPC-style Web Services

Page 38: The State of SOAP in PHP

zomg lol

Page 39: The State of SOAP in PHP

ORIGINSA Brief (and Wildly Inaccurate) History Lesson

Page 40: The State of SOAP in PHP

< 1998

Page 41: The State of SOAP in PHP

XML-RPC

Page 42: The State of SOAP in PHP

XML-RPC sucks

Page 43: The State of SOAP in PHP

1998

Page 44: The State of SOAP in PHP

Simple Object Access Protocol 1.0

Page 45: The State of SOAP in PHP

2003

Page 46: The State of SOAP in PHP

not really simple

Page 47: The State of SOAP in PHP

renamed

Page 48: The State of SOAP in PHP

Simple Object Access Protocol

Page 49: The State of SOAP in PHP

SOAP

Page 50: The State of SOAP in PHP

SOAP 1.2

Page 51: The State of SOAP in PHP

GLOSSARYTransports, Messages and WSDL

Page 52: The State of SOAP in PHP

SOAP TRANSPORTS

• Transports are used for message transmission

• Most important ones:

• HTTP/HTTPS

• SMTP

Page 53: The State of SOAP in PHP

Amazon

Page 54: The State of SOAP in PHP

100.000.000.000 SOAP requests

Page 55: The State of SOAP in PHP

(per second)

Page 56: The State of SOAP in PHP

Sharks

Page 57: The State of SOAP in PHP

(with friggin’ laser beams attached to their heads)

Page 58: The State of SOAP in PHP

Custom Socket Transport

Page 59: The State of SOAP in PHP

MESSAGES

• Wrapped in an <Envelope>

• <Header>s and a <Body>

• Structure is identical for Request and Response

<?xml version="1.0" encoding="UTF‐8"?><SOAP‐ENV:Envelope  xmlns:SOAP‐ENV="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:ns1="http://agavi.org/sampleapp">  <SOAP‐ENV:Body>    <ns1:getProductResponse>      <product>        <id>123456</id>        <name>Red Stapler</name>        <price>3.14</price>      </product>    </ns1:getProductResponse>  </SOAP‐ENV:Body></SOAP‐ENV:Envelope>

Page 60: The State of SOAP in PHP

but worry not

Page 61: The State of SOAP in PHP

that’s the entire point of SOAP

Page 62: The State of SOAP in PHP

WSDL document

Page 63: The State of SOAP in PHP

describes

Page 64: The State of SOAP in PHP

• the service

• the operations

• the data types

Page 65: The State of SOAP in PHP

<?xml version="1.0" encoding="utf‐8"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://agavi.org/sampleapp/types" xmlns:asa="http://agavi.org/sampleapp" name="AgaviSampleApplication" targetNamespace="http://agavi.org/sampleapp">  <wsdl:types>    <xsd:schema xmlns:soap‐enc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://agavi.org/sampleapp/types">      <xsd:complexType name="Product">        <xsd:sequence>          <xsd:element name="id" type="xsd:int"/>          <xsd:element name="name" type="xsd:string"/>          <xsd:element name="price" type="xsd:float"/>        </xsd:sequence>      </xsd:complexType>      <xsd:complexType name="ArrayOfProducts">        <xsd:complexContent>          <xsd:extension base="soap‐enc:Array">            <xsd:attribute ref="soap‐enc:arrayType" wsdl:arrayType="tns:Product[]"/>          </xsd:extension>        </xsd:complexContent>      </xsd:complexType>    </xsd:schema>  </wsdl:types>  <wsdl:portType name="AgaviSampleApplicationPortType">    <wsdl:operation name="getProduct">      <wsdl:input message="asa:getProductRequest"/>      <wsdl:output message="asa:getProductResponse"/>    </wsdl:operation>    <wsdl:operation name="listProducts">      <wsdl:output message="asa:listProductsResponse"/>    </wsdl:operation>  </wsdl:portType>  <binding name="AgaviSampleApplicationBinding" type="asa:AgaviSampleApplicationPortType">    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>    <wsdl:operation name="getProduct">      <soap:operation soapAction="http://agavi.org/sampleapp#getProduct"/>      <wsdl:input>        <soap:body namespace="http://agavi.org/sampleapp" use="literal"/>      </wsdl:input>      <wsdl:output>        <soap:body namespace="http://agavi.org/sampleapp" use="literal"/>      </wsdl:output>    </wsdl:operation>    <wsdl:operation name="listProducts">      <soap:operation soapAction="http://agavi.org/sampleapp#listProducts"/>      <wsdl:output>        <soap:body namespace="http://agavi.org/sampleapp" use="literal"/>      </wsdl:output>    </wsdl:operation>  </binding>  <service name="AgaviSampleApplicationService">    <port name="AgaviSampleApplicationPort" binding="asa:AgaviSampleApplicationBinding">      <soap:address location="http://services.acme.com/soap.php"/>    </port>  </service>  <wsdl:message name="getProductRequest">    <wsdl:part name="id" type="xsd:int"/>  </wsdl:message>  <wsdl:message name="getProductResponse">    <wsdl:part name="product" type="tns:Product"/>  </wsdl:message>  <wsdl:message name="listProductsResponse">    <wsdl:part name="products" type="tns:ArrayOfProducts"/>  </wsdl:message></wsdl:definitions>

Page 66: The State of SOAP in PHP

AN EXAMPLESo We Are All on the Same Page

Page 67: The State of SOAP in PHP

$client = new SoapClient('http://acme.com/product.wsdl', array(  'exceptions' => true,  'trace' => true,));

try {  var_dump($client‐>listProducts());} catch(SoapFault $e) {  // here be dragons}

array  0 =>     object(stdClass)[3]      public 'id' => int 8172401      public 'name' => string 'TPS Report Cover Sheet' (length=22)      public 'price' => float 0.89  1 =>     object(stdClass)[4]      public 'id' => int 917246      public 'name' => string 'Weighted Companion Cube' (length=23)      public 'price' => float 129.99

Page 68: The State of SOAP in PHP

by the way

Page 69: The State of SOAP in PHP

I will not talk about non-WSDL modes

Page 70: The State of SOAP in PHP

because using SOAP without a WSDL is stupid

Page 71: The State of SOAP in PHP

SOAP CLIENTSIf You Want To Consume Services

OMNOMNOM SERVICE

Page 72: The State of SOAP in PHP

BASICS

$client = new SoapClient(  'http://acme.com/product.wsdl', // URL to WSDL describing the service  array( // array of additional options for the client    'exceptions' => true, // throw SoapFault exceptions on errors    'trace' => true, // allow use of SoapClient::__getLast…()  ));

$allProducts = $client‐>listProducts(); // $allProducts contains return value

Page 73: The State of SOAP in PHP

GETTING AVAILABLE FUNCS

$client = new SoapClient('http://acme.com/product.wsdl', array(  'exceptions' => true,  'trace' => true,));

var_dump($client‐>__getFunctions());

array  0 => string 'Product getProduct(int $id)' (length=27)  1 => string 'ArrayOfProducts listProducts()' (length=30)

Page 74: The State of SOAP in PHP

GETTING AVAILABLE TYPES

$client = new SoapClient('http://acme.com/product.wsdl', array(  'exceptions' => true,  'trace' => true,));

var_dump($client‐>__getTypes());

array  0 => string 'struct Product { int id; string name; float price;}' (length=55)  1 => string 'Product ArrayOfProducts[]' (length=25)

Page 75: The State of SOAP in PHP

ADVANCED CONCEPTSFaults, Headers and Mappings

Page 76: The State of SOAP in PHP

FAULT HANDLING

$client = new SoapClient('http://acme.com/product.wsdl', array(  'exceptions' => true,  'trace' => true,));

try {  $newThing = $client‐>createProduct(new stdClass());} catch(SoapFault $e) {  // could be a client‐side fault e.g. if fields are missing  // or a server‐side fault if the server had any objections :)}

Page 77: The State of SOAP in PHP

SOAP HEADERS

$client = new SoapClient('http://acme.com/product.wsdl', array(  'exceptions' => true,  'trace' => true,));

$client‐>setSoapHeader(  new SoapHeader('http://acme.com/soap/products', 'username', 'Chuck Norris'));$client‐>setSoapHeader(  new SoapHeader('http://acme.com/soap/products', 'password', 'r0undh0usek!ck'));

// headers will be sent along with the request$allProducts = $client‐>listProducts();

Page 78: The State of SOAP in PHP

CLASSMAPS

class Product {  protected $id, $name, $price;  // imagine getters and setters here}

$client = new SoapClient('http://acme.com/product.wsdl', array(  'exceptions' => true,  'trace' => true,  'classmap' => array(    'Product' => 'Product', // no namespace here, which can be problematic…  ),));

var_dump($client‐>getProduct(123456));

object(Product)[2]  protected 'id' => int 123456  protected 'name' => string 'Red Stapler' (length=11)  protected 'price' => float 3.14

Page 79: The State of SOAP in PHP

TYPEMAPS

• Used for custom serialization and deserialization

• Needs two callbacks:

• one for XML->PHP conversion

• one for PHP->XML conversion

• Only necessary in very, very rare cases

Page 80: The State of SOAP in PHP

SOAP SERVERSSlightly More Complicated

Page 81: The State of SOAP in PHP

class ProductService {  public function getProduct($id) {    // witchcraft here    return $product;  }  public function listProducts() {    // more witchcraft here    return $products;  }}

$server = new SoapServer('/path/to/local/products.wsdl', array(/* options… */));

// register a class to instantiate that has all the methods$server‐>setClass('ProductService');// alternative: use an existing instance// $server‐>setObject(new ProductService());

// rock and roll$server‐>handle();

A BASIC SERVER

Page 82: The State of SOAP in PHP

you can also register functions instead of class methods

Page 83: The State of SOAP in PHP

wanna know how?

Page 84: The State of SOAP in PHP

RTFM :X

Page 85: The State of SOAP in PHP

class ProductService {  public function getProduct($id) {    // witchcraft here    return $product;  }  public function listProducts() {    // more witchcraft here    return $products;  }  public function username($value) {    // check if it's really chuck norris  }  public function password($value) {    // check if he did a roundhouse kick  }}

$server = new SoapServer('/path/to/local/products.wsdl', array(/* options… */));// register a class to instantiate that has all the methods$server‐>setClass('ProductService');// rock and roll$server‐>handle();

DEALING WITH HEADERS

Page 86: The State of SOAP in PHP

class ProductService {  public function getProduct($id) {    if($product = ProductFinder::retrieveById($id)) {      return $product;    } else {      return new SoapFault('Server', 'No such product');    }  }  public function listProducts() {    // more witchcraft here    return $products;  }}

PRODUCING FAULTS

Page 87: The State of SOAP in PHP

class ProductService {  public function getTwoThings() {    // rocket science here    return array($foo, $bar);  }}

MULTI-PART RETURN VALUES

Page 88: The State of SOAP in PHP

LITTLE SECRETSDid You Know That ext/soap Supports...

Page 89: The State of SOAP in PHP

<complexType name="ArrayOfProducts">  <element name="products" type="foo:Product" maxOccurs="unbounded" /></complexType>

Page 90: The State of SOAP in PHP

{http://xml.apache.org/xml-soap}Map

Page 91: The State of SOAP in PHP

LITTLE DISAPPOINTMENTSThings That ext/soap Does Not Support...

Page 92: The State of SOAP in PHP

DateTime objects

Page 93: The State of SOAP in PHP

document/literal wrapped

Page 94: The State of SOAP in PHP

DOS AND DON’TSKeep This in Mind

Page 95: The State of SOAP in PHP

enable the SOAP_SINGLE_ELEMENT_ARRAYS feature

Page 96: The State of SOAP in PHP

don’t use SoapServer::fault()

Page 97: The State of SOAP in PHP

use the exceptions option

Page 98: The State of SOAP in PHP

double-check soap_use_error_handler()

Page 99: The State of SOAP in PHP

don’t use cookies or other forms of state, ever

Page 100: The State of SOAP in PHP

FRAMEWORK HIGHLIGHTSZend Framework & Agavi

Page 101: The State of SOAP in PHP

ZEND FRAMEWORK

• Zend_Soap_Client as a wrapper for SOAPClient

• Zend_Soap_Server as a wrapper for SOAPServer

• Zend_Soap_Wsdl for constructing WSDL documents

• Zend_Soap_Autodiscover for automatic WSDL generation

Page 102: The State of SOAP in PHP

Zend_Soap_Autodiscover generates WSDLs for you!

Page 103: The State of SOAP in PHP

using PHPDoc comments

Page 104: The State of SOAP in PHP

class AcmeProductService {  /**   * @param      int     The ID of the product.   *   * @return     Product The product object.   *   * @deprecated Call Joe from sales if you want to know details about a product…   */  public function getProduct($id) {    // witchcraft goes here    return $product;  }}

$autodiscover = new Zend_Soap_AutoDiscover();$autodiscover‐>setClass('AcmeProductService');$autodiscover‐>handle(); // dumps a WSDL

Page 105: The State of SOAP in PHP

also very nice for prototyping

Page 106: The State of SOAP in PHP

but might get difficult with complex stuff

Page 107: The State of SOAP in PHP

AGAVI

• Re-use existing Actions for SOAP Services

• Needs some information about the service in WSDL format

• WSDL auto-generated by the Routing

• Requires basic knowledge of XML Schema and WSDL

• Supports Document/Literal Wrapped for Servers

Page 108: The State of SOAP in PHP

Demo

Page 109: The State of SOAP in PHP

SOAP VERSUS RESTYour Thoughts Please

Page 110: The State of SOAP in PHP

!e End

Page 111: The State of SOAP in PHP

Questions?

Page 112: The State of SOAP in PHP

THANK YOU!

• Shoot me an E-Mail: [email protected]

• Follow @dzuelke on Twitter

• Slides will be online at http://talks.wombert.de/