The State of SOAP in PHP

  • 7,398 views
Uploaded on

Presentation at PHP Barcelona 2009

Presentation at PHP Barcelona 2009

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
7,398
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
57
Comments
0
Likes
2

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. apologies
  • 5. http://flic.kr/chrismetcalf/43098186/
  • 6. http://flic.kr/waltjabsco/3598975570/
  • 7. back from
  • 8. ZendCon
  • 9. ✈ ✈
  • 10. ✈
  • 11. http://en.wikipedia.org/wiki/File:München_Panorama.JPG
  • 12. Founder
  • 13. awesome
  • 14. Lead Developer
  • 15. @dzuelke
  • 16. WHAT IS SOAP? And How Did It All Start?
  • 17. original plan
  • 18. talk
  • 19.  dis is srs bsns
  • 20. make
  • 21. Kit tY Inc No lu t de d http://flic.kr/kevinsteele/230997861/
  • 22.
  • 23. however
  • 24. http://en.wikipedia.org/wiki/File:Flughafenkontrolle.jpg
  • 25. risk
  • 26. SHOOT ME IN THE FACE
  • 27. WHAT IS SOAP? And How Did It All Start?
  • 28. Data Exchange Protocol
  • 29. XML-based
  • 30. language independent
  • 31. platform independent
  • 32. typically used for RPC-style Web Services
  • 33.  zomg lol
  • 34. ORIGINS A Brief (and Wildly Inaccurate) History Lesson
  • 35. < 1998
  • 36. XML-RPC
  • 37. XML-RPC sucks
  • 38. 1998
  • 39. Simple Object Access Protocol 1.0
  • 40. 2003
  • 41. not really simple
  • 42. renamed
  • 43. Simple Object Access Protocol
  • 44. SOAP
  • 45. SOAP 1.2
  • 46. GLOSSARY Transports, Messages and WSDL
  • 47. SOAP TRANSPORTS • Transports are used for message transmission • Most important ones: • HTTP/HTTPS • SMTP
  • 48. Amazon
  • 49. 100.000.000.000 SOAP requests
  • 50. (per second)
  • 51. Sharks
  • 52. (with friggin’ laser beams attached to their heads)
  • 53. Custom Socket Transport
  • 54. MESSAGES <?xml version="1.0" encoding="UTF‐8"?> <SOAP‐ENV:Envelope   xmlns:SOAP‐ENV="http:// schemas.xmlsoap.org/soap/envelope/" • Wrapped in an <Envelope>   xmlns:ns1="http://agavi.org/ sampleapp" > • <Header>s and a <Body>   <SOAP‐ENV:Body>     <ns1:getProductResponse>       <product>         <id>123456</id> • Structure is identical for         <name>Red Stapler</name>         <price>3.14</price> Request and Response       </product>     </ns1:getProductResponse>   </SOAP‐ENV:Body> </SOAP‐ENV:Envelope>
  • 55. but worry not
  • 56. that’s the entire point of SOAP
  • 57. WSDL document
  • 58. describes
  • 59. • the service • the operations • the data types
  • 60. <?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"/>
  • 61. AN EXAMPLE So We Are All on the Same Page
  • 62. $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
  • 63. by the way
  • 64. I will not talk about non-WSDL modes
  • 65. because using SOAP without a WSDL is stupid
  • 66. SOAP CLIENTS If You Want To Consume Services OMNOMNOM SERVICE
  • 67. 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
  • 68. 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)
  • 69. 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)
  • 70. ADVANCED CONCEPTS Faults, Headers and Mappings
  • 71. 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 :) }
  • 72. 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();
  • 73. 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
  • 74. 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
  • 75. SOAP SERVERS Slightly More Complicated
  • 76. A BASIC SERVER 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();
  • 77. you can also register functions instead of class methods
  • 78. wanna know how?
  • 79. RTFM :X
  • 80. DEALING WITH HEADERS 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();
  • 81. PRODUCING FAULTS 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;   } }
  • 82. MULTI-PART RETURN VALUES class ProductService {   public function getTwoThings() {     // rocket science here     return array($foo, $bar);   } }
  • 83. LITTLE SECRETS Did You Know That ext/soap Supports...
  • 84. <complexType name="ArrayOfProducts">   <element name="products" type="foo:Product" maxOccurs="unbounded" /> </complexType>
  • 85. {http://xml.apache.org/xml-soap}Map
  • 86. LITTLE DISAPPOINTMENTS Things That ext/soap Does Not Support...
  • 87. DateTime objects
  • 88. document/literal wrapped
  • 89. DOS AND DON’TS Keep This in Mind
  • 90. enable the SOAP_SINGLE_ELEMENT_ARRAYS feature
  • 91. don’t use SoapServer::fault()
  • 92. use the exceptions option
  • 93. double-check soap_use_error_handler()
  • 94. don’t use cookies or other forms of state, ever
  • 95. FRAMEWORK HIGHLIGHTS Zend Framework & Agavi
  • 96. 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
  • 97. Zend_Soap_Autodiscover generates WSDLs for you!
  • 98. using PHPDoc comments
  • 99. 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
  • 100. also very nice for prototyping
  • 101. but might get difficult with complex stuff
  • 102. 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
  • 103. Demo
  • 104. SOAP VERSUS REST Your Thoughts Please
  • 105. !e End
  • 106. Questions?
  • 107. THANK YOU! • Shoot me an E-Mail: david.zuelke@bitextender.com • Follow @dzuelke on Twitter • Slides will be online at http://talks.wombert.de/