Your SlideShare is downloading. ×
0
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
The State of SOAP in PHP (ZC10 2010-11-02)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

The State of SOAP in PHP (ZC10 2010-11-02)

3,385

Published on

Presentation given at ZendCon 2010.

Presentation given at ZendCon 2010.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,385
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
87
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. THE STATE OF SOAP IN PHP
  • 2. David Zülke
  • 3. David Zuelke
  • 4. http://en.wikipedia.org/wiki/File:EU-Germany.svg
  • 5. http://en.wikipedia.org/wiki/File:München_Panorama.JPG
  • 6. Founder
  • 7. Lead Developer
  • 8. @dzuelke
  • 9. WHAT IS SOAP? And How Did It All Start?
  • 10. original plan
  • 11. talk
  • 12. make
  • 13. http://flic.kr/kevinsteele/230997861/
  • 14. 
  • 15. however
  • 16. ✈
  • 17. http://de.wikipedia.org/wiki/Datei:Vorfeld_Terminal_1_I.JPG
  • 18. http://en.wikipedia.org/wiki/File:Flughafenkontrolle.jpg
  • 19. http://flic.kr/himmelskratzer/2604824645/
  • 20. NEIN NEIN NEIN NEIN DAS IST VERBOTEN
  • 21. 
  • 22. WHAT IS SOAP? And How Did It All Start?
  • 23. Data Exchange Protocol
  • 24. XML-based
  • 25. language independent
  • 26. platform independent
  • 27. typically used for RPC-style Web Services
  • 28. zomg lol
  • 29. ORIGINS A Brief (and Wildly Inaccurate) History Lesson
  • 30. < 1998
  • 31. XML-RPC
  • 32. XML-RPC sucks
  • 33. 1998
  • 34. Simple Object Access Protocol 1.0
  • 35. 2003
  • 36. not really simple
  • 37. renamed
  • 38. Simple Object Access Protocol
  • 39. SOAP
  • 40. SOAP 1.2
  • 41. GLOSSARY Transports, Messages and WSDL
  • 42. SOAPTRANSPORTS • Transports are used for message transmission • Most important ones: • HTTP/HTTPS • SMTP
  • 43. Amazon
  • 44. 100.000.000.000 SOAP requests
  • 45. (per second)
  • 46. Sharks
  • 47. (with friggin’ laser beams attached to their heads)
  • 48. Custom SocketTransport and Serialization!
  • 49. MESSAGES • Wrapped in <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>
  • 50. but worry not
  • 51. that’s the entire point of SOAP
  • 52. WSDL document
  • 53. describes
  • 54. • the service • the operations • the data types
  • 55. <?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"/>
  • 56. AN EXAMPLE So We Are All on the Same Page
  • 57. $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
  • 58. by the way
  • 59. I will not talk about non-WSDL modes
  • 60. I'd rather stab myself than use SOAP without WSDL
  • 61. SOAP CLIENTS IfYou WantTo Consume Services OMNOMNOM SERVICE
  • 62. 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
  • 63. 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)
  • 64. GETTING AVAILABLETYPES $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)
  • 65. ADVANCED CONCEPTS Faults, Headers and Mappings
  • 66. 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  :) }
  • 67. 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();
  • 68. 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  XML  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
  • 69. ext/soap cannot distinguish between identically named types from different namespaces
  • 70. TYPEMAPS • Used for custom serialization and unserialization in rare cases • Example: • xsd:long is mapped to PHP int, overflows on 32bit archs • Needs two callbacks: • one for XML->PHP conversion • one for PHP->XML conversion
  • 71. TYPEMAP EXAMPLE: XS:LONG function  to_long_xml($longVal)  {    return  '<long>'  .  $longVal  .  '</long>'; } function  from_long_xml($xmlFragmentString)  {    return  (string)strip_tags($xmlFragmentString); } $client  =  new  SoapClient('http://acme.com/products.wsdl',  array(    'typemap'  =>  array(        array(            'type_ns'  =>  'http://www.w3.org/2001/XMLSchema',            'type_name'  =>  'long',            'to_xml'  =>  'to_long_xml',            'from_xml'  =>  'from_long_xml',        ),    ), )); you can use any name for this wrapper tag
  • 72. SOAP SERVERS Slightly More Complicated
  • 73. 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
  • 74. you can also register functions instead of class methods
  • 75. wanna know how?
  • 76. RTFM :X
  • 77. 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
  • 78. again, it can’t tell headers from different namespaces apart
  • 79. 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
  • 80. class  ProductService  {    public  function  getTwoThings()  {        //  rocket  science  here        return  array($product1,  $product2);    } } MULTI-PART RETURNVALUES <wsdl:message  name="getTwoThingsRequest">    <wsdl:part  name="id1"  type="xsd:int"/>    <wsdl:part  name="id2"  type="xsd:int"/> </wsdl:message> <wsdl:message  name="getTwoThingsResponse">    <wsdl:part  name="firstThing"  type="tns:Product"/>    <wsdl:part  name="secondThing"  type="tns:Product"/> </wsdl:message> list($p1,  $p2)  =  $client-­‐>getTwoThings($id1,  $id2));
  • 81. LITTLE SECRETS DidYou KnowThat ext/soap Supports...
  • 82. <complexType  name="ArrayOfProducts">    <element  name="products"  type="foo:Product"  maxOccurs="unbounded"  /> </complexType> XML SCHEMA ARRAYS <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> =
  • 83. HASHMAPS (W/ STRING KEYS) <xsd:schema    xmlns:apache-­‐enc="http:// xml.apache.org/xml-­‐soap">    <xsd:complexType  name="MyHashmap">        <xsd:element            name="parameters"            type="apache-­‐enc:Map"  />    </xsd:complexType> </xsd:schema> • Custom Apache Axis encoding style • be aware that it won’t offer good interoperability • Use any type for values, scalars for keys • Keys and values will use RPC encoding in the message
  • 84. ONE-WAY CALLS • SOAP Operations may have only a request, without a response declared • Both SoapClient and SoapServer will close the connection as soon as they can when calling such a method http://flic.kr/99996581@N00/1122331674/
  • 85. LITTLE DISAPPOINTMENTS ThingsThat ext/soap Does Not Support...
  • 86. DateTime objects
  • 87. but you can use type maps until there is support! o/
  • 88. XSD:DATETIMETYPE MAP function  to_datetime_xml(DateTime  $dateTime)  {    return  '<dateTime>'.$dateTime-­‐>format('Y-­‐m-­‐dTH:i:sP').'</dateTime>'; } function  from_datetime_xml($xmlFragmentString)  {    return  new  DateTime(strip_tags($xmlFragmentString)); } $client  =  new  SoapClient('http://acme.com/products.wsdl',  array(    'typemap'  =>  array(        array(            'type_ns'  =>  'http://www.w3.org/2001/XMLSchema',            'type_name'  =>  'dateTime',            'to_xml'  =>  'to_datetime_xml',            'from_xml'  =>  'from_datetime_xml',        ),    ), ));
  • 89. DOCUMENT/LITERAL WRAPPED • Document style services yield messages that can be validated against the WSDL’s XML Schema • Unlike with RPC style services, such messages won’t contain the name of the called method anymore • Solution: wrap the message payload in an element that has the same name as the procedure you want to call • Not a problem in PHP, but you need to wrap/unwrap yourself
  • 90. DOS AND DON’TS KeepThis in Mind
  • 91. enable the SOAP_SINGLE_ELEMENT_ARRAYS feature
  • 92. don’t use SoapServer::fault()
  • 93. use the exceptions option
  • 94. double-check soap_use_error_handler()
  • 95. don’t use cookies or other forms of state, ever
  • 96. FRAMEWORK HIGHLIGHTS Zend Framework & Agavi
  • 97. 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 auto WSDL generation
  • 98. Zend_Soap_Autodiscover generates WSDLs for you!
  • 99. using PHPDoc comments
  • 100. 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();  //  only  dumps  a  WSDL,  does  not  start  a  server!
  • 101. also very nice for prototyping
  • 102. but might get difficult with complex stuff
  • 103. e.g. multi-dimensional arrays, can’t do those in PHPDoc
  • 104. 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
  • 105. Demo
  • 106. SOAPVERSUS REST A Short Monologue
  • 107. !e End
  • 108. Questions?
  • 109. THANKYOU! This was http://joind.in/2231 by @dzuelke

×