Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Working with Web Services Lorna Mitchell October 2009
Who am I? <ul><li>Lorna Mitchell
PHP Developer/Consultant/Trainer at Ibuildings
Personal site at lornajane.net
European Rep for PHPWomen.org
PHPNW organiser
Twitter: @lornajane </li></ul>
Working with Web Services <ul><li>Consuming existing services
Web services overview
Data types
Service types
Debugging
Using services from PHP </li></ul>
What are Web Services? <ul><li>Machine-friendly applications
Formatted data instead of a web page </li></ul>
Why Do We Care? <ul><li>Web services let us exchange data  </li><ul><li>between systems
within systems </li></ul><li>Architecture looks like library or module boundary
Sharing information between systems cleanly </li></ul>
How do Web Services Work? <ul><li>Client/Server
Sound familiar?
Request and response, just like a web application
Same theories apply </li></ul>
When Things Go Wrong <ul><li>Errors will appear in response
We may not expect them
Apache logs
Debug output and logging
Verbose error-checking and logging from our app
Graceful failure </li></ul>
Data Formats
JSON <ul><li>JavaScript Object Notation
Natively read/write in most languages
Very simple! (we like simple)
Limitations </li><ul><li>no data typing
no distinction between object and array </li></ul></ul>
Writing JSON from PHP 1  < ?php 2  3  $menu [ 'starter' ] =   array (   &quot;prawn cocktail&quot; , 4  &quot;soup of the ...
Reading JSON from PHP 1  < ?php 2  3  $json   =   '{&quot;starter&quot;:[&quot;prawn cocktail&quot;,&quot;soup of the day&...
Reading JSON from PHP stdClass Object ( [starter] => Array ( [0] => prawn cocktail [1] => soup of the day ) [main course] ...
XML <ul><li>eXtensible Markup Language
Familiar
Can give more detail than JSON
Native read/write in most languages </li></ul>
Working with XML from PHP <ul><li>Lots of options
SimpleXML
DOM </li></ul>
SimpleXML Example 1  < ?php 2  3  $xml   = <<<   XML 4  < ?xml version = &quot;1.0&quot;  ? > 5  < menus > 6  < menu > Lun...
SimpleXML Example object(SimpleXMLElement)#1 (1) { [&quot;menu&quot;]=> array(5) { [0]=> string(5) &quot;Lunch&quot; [1]=>...
SimpleXML Example 1  < ?php 2  3  $simplexml   =   simplexml_load_string ( '<?xml version=&quot;1.0&quot; ?><menus/>' ); 4...
SimpleXML Example <?xml version=&quot;1.0&quot;?> <menus> <menu>Lunch</menu> <menu>Dinner</menu> <menu>Dessert</menu> <men...
Serialised PHP <ul><li>Native to PHP
Useful for values in database
Can also use to move data between PHP applications </li></ul>
Serialising Data in PHP 1  < ?php 2  3  $menu [ 'starter' ] =   array (   &quot;prawn cocktail&quot; , 4  &quot;soup of th...
Unserialising Data in PHP 1  < ?php 2  3  $serialised   =   'a:3:{s:7:&quot;starter&quot;;a:2:{i:0;s:14:&quot;prawn cockta...
Unserialising Data in PHP array(3) { [&quot;starter&quot;]=> array(2) { [0]=> string(14) &quot;prawn cocktail&quot; [1]=> ...
Service Types
Service Types <ul><li>SOAP
*-RPC </li></ul><ul><ul><li>XML-RPC
JSON-RPC </li></ul></ul><ul><li>REST </li></ul>
SOAP <ul><li>Just &quot;soap&quot;
Defined XML format
Upcoming SlideShare
Loading in …5
×

Working with Web Services

This is a PHP talk about consuming web services, dealing with XML and JSON and serialised PHP. It covers use of services using SOAP, XML-RPC, JSON-RPC and some RESTful concepts with plenty of code examples. Examples of making web service clients using streams, pecl_http and curl are included

  • Be the first to comment

Working with Web Services

  1. 1. Working with Web Services Lorna Mitchell October 2009
  2. 2. Who am I? <ul><li>Lorna Mitchell
  3. 3. PHP Developer/Consultant/Trainer at Ibuildings
  4. 4. Personal site at lornajane.net
  5. 5. European Rep for PHPWomen.org
  6. 6. PHPNW organiser
  7. 7. Twitter: @lornajane </li></ul>
  8. 8. Working with Web Services <ul><li>Consuming existing services
  9. 9. Web services overview
  10. 10. Data types
  11. 11. Service types
  12. 12. Debugging
  13. 13. Using services from PHP </li></ul>
  14. 14. What are Web Services? <ul><li>Machine-friendly applications
  15. 15. Formatted data instead of a web page </li></ul>
  16. 16. Why Do We Care? <ul><li>Web services let us exchange data </li><ul><li>between systems
  17. 17. within systems </li></ul><li>Architecture looks like library or module boundary
  18. 18. Sharing information between systems cleanly </li></ul>
  19. 19. How do Web Services Work? <ul><li>Client/Server
  20. 20. Sound familiar?
  21. 21. Request and response, just like a web application
  22. 22. Same theories apply </li></ul>
  23. 23. When Things Go Wrong <ul><li>Errors will appear in response
  24. 24. We may not expect them
  25. 25. Apache logs
  26. 26. Debug output and logging
  27. 27. Verbose error-checking and logging from our app
  28. 28. Graceful failure </li></ul>
  29. 29. Data Formats
  30. 30. JSON <ul><li>JavaScript Object Notation
  31. 31. Natively read/write in most languages
  32. 32. Very simple! (we like simple)
  33. 33. Limitations </li><ul><li>no data typing
  34. 34. no distinction between object and array </li></ul></ul>
  35. 35. Writing JSON from PHP 1 < ?php 2 3 $menu [ 'starter' ] = array ( &quot;prawn cocktail&quot; , 4 &quot;soup of the day&quot; ); 5 $menu [ 'main course' ] = array ( &quot;roast chicken&quot; , 6 &quot;fish 'n' chips&quot; , 7 &quot;macaroni cheese&quot; ); 8 $menu [ 'pudding' ] = array ( &quot;cheesecake&quot; , 9 &quot;treacle sponge&quot; ); 10 11 echo json_encode ( $menu ); {&quot;starter&quot;:[&quot;prawn cocktail&quot;,&quot;soup of the day&quot;],&quot;main course&quot;:[&quot;roast chicken&quot;,&quot;fish 'n' chips&quot;,&quot;macaroni cheese&quot;],&quot;pudding&quot;:[&quot;cheesecake&quot;,&quot;treacle sponge&quot;]}
  36. 36. Reading JSON from PHP 1 < ?php 2 3 $json = '{&quot;starter&quot;:[&quot;prawn cocktail&quot;,&quot;soup of the day&quot;],&quot;main course&quot;:[&quot;roast chicken&quot;,&quot;fish ' n ' chips&quot;,&quot;macaroni cheese&quot;],&quot;pudding&quot;:[&quot;cheesecake&quot;,&quot;treacle sponge&quot;]}' ; 4 5 print_r ( json_decode ( $json ));
  37. 37. Reading JSON from PHP stdClass Object ( [starter] => Array ( [0] => prawn cocktail [1] => soup of the day ) [main course] => Array ( [0] => roast chicken [1] => fish 'n' chips [2] => macaroni cheese ) [pudding] => Array ( [0] => cheesecake [1] => treacle sponge ) )
  38. 38. XML <ul><li>eXtensible Markup Language
  39. 39. Familiar
  40. 40. Can give more detail than JSON
  41. 41. Native read/write in most languages </li></ul>
  42. 42. Working with XML from PHP <ul><li>Lots of options
  43. 43. SimpleXML
  44. 44. DOM </li></ul>
  45. 45. SimpleXML Example 1 < ?php 2 3 $xml = <<< XML 4 < ?xml version = &quot;1.0&quot; ? > 5 < menus > 6 < menu > Lunch </ menu > 7 < menu > Dinner </ menu > 8 < menu > Dessert </ menu > 9 < menu > Drinks </ menu > 10 </ menus > 11 XML ; 12 13 $simplexml = new SimpleXMLElement ( $xml ); 14 var_dump ( $simplexml );
  46. 46. SimpleXML Example object(SimpleXMLElement)#1 (1) { [&quot;menu&quot;]=> array(5) { [0]=> string(5) &quot;Lunch&quot; [1]=> string(6) &quot;Dinner&quot; [2]=> string(7) &quot;Dessert&quot; [3]=> string(6) &quot;Drinks&quot; } }
  47. 47. SimpleXML Example 1 < ?php 2 3 $simplexml = simplexml_load_string ( '<?xml version=&quot;1.0&quot; ?><menus/>' ); 4 $simplexml -> addChild ( 'menu' , 'Lunch' ); 5 $simplexml -> addChild ( 'menu' , 'Dinner' ); 6 $simplexml -> addChild ( 'menu' , 'Drinks' ); 7 $simplexml -> addChild ( 'menu' , 'Dessert' ); 8 9 echo $simplexml -> asXML ();
  48. 48. SimpleXML Example <?xml version=&quot;1.0&quot;?> <menus> <menu>Lunch</menu> <menu>Dinner</menu> <menu>Dessert</menu> <menu>Drinks</menu> </menus>
  49. 49. Serialised PHP <ul><li>Native to PHP
  50. 50. Useful for values in database
  51. 51. Can also use to move data between PHP applications </li></ul>
  52. 52. Serialising Data in PHP 1 < ?php 2 3 $menu [ 'starter' ] = array ( &quot;prawn cocktail&quot; , 4 &quot;soup of the day&quot; ); 5 $menu [ 'main course' ] = array ( &quot;roast chicken&quot; , 6 &quot;fish 'n' chips&quot; , 7 &quot;macaroni cheese&quot; ); 8 $menu [ 'pudding' ] = array ( &quot;cheesecake&quot; , 9 &quot;treacle sponge&quot; ); 10 11 echo serialize ( $menu ); a:3:{s:7:&quot;starter&quot;;a:2:{i:0;s:14:&quot;prawn cocktail&quot;;i:1;s:15:&quot;soup of the day&quot;;}s:11:&quot;main course&quot;;a:3:{i:0;s:13:&quot;roast chicken&quot;;i:1;s:14:&quot;fish'n' chips&quot;;i:2;s:15:&quot;macaroni cheese&quot;;}s:7:&quot;pudding&quot;;a:2:{i:0;s:10:&quot;cheesecake&quot;;i:1;s:14:&quot;treacle sponge&quot;;}}
  53. 53. Unserialising Data in PHP 1 < ?php 2 3 $serialised = 'a:3:{s:7:&quot;starter&quot;;a:2:{i:0;s:14:&quot;prawn cocktail&quot;;i:1;s:15:&quot;soup of the day&quot;;}s:11:&quot;main course&quot;;a:3:{i:0;s:13:&quot;roast chicken&quot;;i:1;s:14:&quot;fish ' n ' chips&quot;;i:2;s:15:&quot;macaroni cheese&quot;;}s:7:&quot;pudding&quot;;a:2:{i:0;s:10:&quot;cheesecake&quot;;i:1;s:14:&quot;treacle sponge&quot;;}}' ; 4 5 var_dump ( unserialize ( $serialised ));
  54. 54. Unserialising Data in PHP array(3) { [&quot;starter&quot;]=> array(2) { [0]=> string(14) &quot;prawn cocktail&quot; [1]=> string(15) &quot;soup of the day&quot; } [&quot;main course&quot;]=> array(3) { [0]=> string(13) &quot;roast chicken&quot; [1]=> string(14) &quot;fish 'n' chips&quot; [2]=> string(15) &quot;macaroni cheese&quot; } [&quot;pudding&quot;]=> array(2) { [0]=> string(10) &quot;cheesecake&quot; [1]=> string(14) &quot;treacle sponge&quot; } }
  55. 55. Service Types
  56. 56. Service Types <ul><li>SOAP
  57. 57. *-RPC </li></ul><ul><ul><li>XML-RPC
  58. 58. JSON-RPC </li></ul></ul><ul><li>REST </li></ul>
  59. 59. SOAP <ul><li>Just &quot;soap&quot;
  60. 60. Defined XML format
  61. 61. Also includes definition for error format
  62. 62. Wrappers available for most languages
  63. 63. Optionally uses a WSDL to describe the service </li></ul><ul><ul><li>Web Service Description Language </li></ul></ul>http://www.flickr.com/photos/kerryw/3824338526
  64. 64. Example WSDL <?xml version ='1.0' encoding ='UTF-8' ?> <definitions name='MyClass' targetNamespace='urn:MyClassInventory' xmlns:tns='urn:MyClassInventory' xmlns:soap=' http://schemas.xmlsoap.org/wsdl/soap/ ' xmlns:xsd=' http://www.w3.org/2001/XMLSchema ' xmlns:soapenc=' http://schemas.xmlsoap.org/soap/encoding/ ' xmlns:wsdl=' http://schemas.xmlsoap.org/wsdl/ ' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='getAccountStatusRequest'> <part name='accountID' type='xsd:string'/> </message> <message name='getAccountStatusResponse'> <part name='accountID' type='xsd:string'/> <part name='counter' type='xsd:float' /> </message> <portType name='MyClassPortType'> <operation name='getAccountStatus'> <input message='tns:getAccountStatusRequest'/> <output message='tns:getAccountStatusResponse'/> </operation> </portType> <binding name='MyClassBinding' type='tns:MyClassPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getAccountStatus'> <soap:operation soapAction='urn:xmethods-delayed-quotes#getAccountStatus'/> <input> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding> <service name='MyClassService'> <port name='MyClassPort' binding='tns:MyClassBinding'> <soap:address location='http://rivendell.local:10002/MyClassServiceServer.php'/> </port> </service> </definitions>
  65. 65. WSDL tips <ul><li>Read from end to beginning </li></ul><ul><ul><li>Service location and name
  66. 66. Method names and bindings
  67. 67. Details of request/response messages
  68. 68. Variable names and data types used for each request/response
  69. 69. Data type definitions
  70. 70. Namespace information </li></ul></ul>
  71. 71. PHP SOAP Client Example 1 < ?php 2 3 ini_set ( 'soap.wsdl_cache_enabled' , '0' ); 4 5 require_once ( 'lib/Snapshot.php' ); 6 7 $wsdl = &quot;Service.wsdl&quot; ; 8 $client = new SoapClient ( $wsdl , $params ); 9 10 $output = $client -> requestShot ( 11 'http://www.php.net' , '' , 300 , 400 );
  72. 72. Troubleshooting SOAP <ul><li>Check request </li><ul><li>$client->getLastRequest() </li></ul><li>Check request headers </li><ul><li>$client->getLastRequestHeaders() </li></ul><li>Check WSDL
  73. 73. Data types can be an issue between different client/server languages </li></ul>
  74. 74. HTTP Debugging Tools <ul><li>cURL </li><ul><li>http://curl.haxx.se/ </li></ul><li>Wireshark </li><ul><li>http://www.wireshark.org/ </li></ul><li>Charles </li></ul><ul><ul><li>http://www.charlesproxy.com/ </li></ul></ul>
  75. 75. cURL <ul><li>cURL is a command-line tool
  76. 76. Simple but powerful
  77. 77. Specify HTTP verb
  78. 78. Observe full request/response headers
  79. 79. Handle cookies </li></ul>
  80. 80. cURL Cheat Sheet <ul><li>curl http://localhost
  81. 81. -v to show request/response
  82. 82. -I to show response headers
  83. 83. -X to specify HTTP method
  84. 84. -d to add a data field
  85. 85. -c to store cookies in a cookiejar
  86. 86. -b to use a cookiejar with request </li></ul>
  87. 87. Wireshark Examples
  88. 88. Wireshark Examples
  89. 89. Wireshark Examples
  90. 90. Wireshark Examples
  91. 91. RPC Services <ul><li>Remote Procedure Call
  92. 92. Similar to library
  93. 93. Call function with arguments </li></ul>
  94. 94. Example RPC services <ul><li>Using Flickr's XML-RPC
  95. 95. Test method: just echoes back to user
  96. 96. XML formatted data </li></ul>
  97. 97. Flickr Echo Example: XML <?xml version = &quot;1.0&quot;?> <methodCall> <methodName> flickr.test.echo </methodName> <params> <param> <value> <struct> <member> <name> api_key </name> <value>....</value> </member> </struct> </value> </param> </params> </methodCall>
  98. 98. RPC from PHP: curl 1 < ?php 2 3 // $xml is existing SimpleXMLElement Object 4 $url = 'http://api.flickr.com/services/xmlrpc/' ; 5 $ch = curl_init ( $url ); 6 7 curl_setopt ( $ch , CURLOPT_POST , 1 ); 8 curl_setopt ( $ch , CURLOPT_POSTFIELDS , $xml -> asXML ()); 9 10 $response = curl_exec ( $ch ); 11 curl_close ( $ch );
  99. 99. RPC from PHP: pecl_http 1 < ?php 2 3 $url = 'http://api.flickr.com/services/xmlrpc/' ; 4 5 // procedural method 6 $response = http_post_data ( $url , $xml -> asXML ()); 7 8 // alternative method 9 $request = new HTTPRequest ( $url , HTTP_METH_POST ); 10 $request -> setRawPostData ( $xml -> asXML ()); 11 $request -> send (); 12 $response = $request -> getResponseBody (); 13 14 var_dump ( $response );
  100. 100. Flickr Response <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?> <methodResponse> <params> <param> <value> <string>&lt;api_key&gt;54rt346&lt;/api_key&gt; </string> </value> </param> </params> </methodResponse>
  101. 101. Wrapping RPC <ul><li>RPC is a library-like interface
  102. 102. Can easily wrap existing libraries to call like this
  103. 103. Can wrap an interface to an RPC service to look like a library </li></ul>
  104. 104. Wrapping RPC Example 1 < ?php 2 3 class Handler 4 { 5 function __call ( $method , $args ) { 6 $ch = curl_init ( 'http://localhost' ); 7 $data [ 'method' ] = $method ; 8 foreach ( $args as $a ) $data [ $a ] = $a ; 9 10 curl_setopt ( $ch , CURLOPT_POST , 1 ); 11 curl_setopt ( $ch , CURLOPT_POSTFIELDS , $data ); 12 $response = curl_exec ( $ch ); curl_close ( $ch ); 13 14 var_dump ( $response ); 15 } 16 } 17 $h = new Handler (); 18 $h -> dance ( 'cat' , 'dog' , 'rabbit' , 'penguin' ); 19
  105. 105. Troubleshooting RPC <ul><li>Break down into smallest steps
  106. 106. Can you get a response from the service?
  107. 107. Can you log in?
  108. 108. Is there an error?
  109. 109. Try to debug the details of the request/response </li></ul>
  110. 110. REST <ul><li>REpresentational State Transfer
  111. 111. Not a protocol
  112. 112. More like a philosophy </li></ul>http://www.flickr.com/photos/katiew/191128057/
  113. 113. REST Overview <ul><li>A series of concepts
  114. 114. Generally uses HTTP (HyperText Transfer Protocol)
  115. 115. URLs are resource locations
  116. 116. Verbs tell the service what to do
  117. 117. Status codes indicate what the outcome was </li></ul>
  118. 118. HTTP Status Codes Code Meaning 200 OK 302 Found 301 Moved 401 Not Authorised 403 Forbidden 404 Not Found 500 Internal Server Error
  119. 119. REST CRUD Action HTTP Verb Retrieve GET Create POST Update PUT Delete DELETE
  120. 120. REST Examples <ul><li>GET </li><ul><li>http://localhost/users
  121. 121. http://localhost/users/harry </li></ul><li>POST </li><ul><li>http://localhost/users </li></ul><li>PUT </li><ul><li>http://localhost/users/harry </li></ul><li>DELETE </li><ul><li>http://localhost/users/harry </li></ul></ul>
  122. 122. REST from PHP: GET 1 < ?php 2 3 $result = file_get_contents ( 'http://localhost/users' ); 4 var_dump ( $result );
  123. 123. REST from PHP: GET <ul><li>Health Warning! </li><ul><li>curl will echo output
  124. 124. use CURLOPT_RETURNTRANSFER to capture it instead </li></ul></ul>1 < ?php 2 3 $ch = curl_init ( 'http://localhost/users' ); 4 5 curl_exec ( $ch );
  125. 125. REST from PHP: POST 1 < ?php 2 3 $ch = curl_init ( 'http://localhost/users' ); 4 5 $data = array ( &quot;name&quot; => &quot;Cho Chang&quot; , 6 &quot;house&quot; => &quot;Ravenclaw&quot; ); 7 8 curl_setopt ( $ch , CURLOPT_POST , 1 ); 9 curl_setopt ( $ch , CURLOPT_POSTFIELDS , $data ); 10 11 curl_exec ( $ch );
  126. 126. REST from PHP: PUT 1 < ?php 2 3 $ch = curl_init ( 'http://localhost/users/cho' ); 4 5 $data = array ( &quot;name&quot; => &quot;Cho Chang&quot; , 6 &quot;house&quot; => &quot;Ravenclaw&quot; 7 &quot;age&quot; => 15 ); 8 9 curl_setopt ( $handle , CURLOPT_CUSTOMREQUEST , 'PUT' ); 10 curl_setopt ( $ch , CURLOPT_POSTFIELDS , $data ); 11 12 curl_exec ( $ch ); 13
  127. 127. REST from PHP: DELETE 1 < ?php 2 3 $ch = curl_init ( 'http://localhost/users/ginny' ); 4 5 curl_setopt ( $ch , CURLOPT_CUSTOMREQUEST , 'DELETE' ); 6 7 curl_exec ( $ch );
  128. 128. Troubleshooting REST <ul><li>Does resource exist?
  129. 129. Is there a status code?
  130. 130. What does the response body look like?
  131. 131. Intercept web traffic
  132. 132. Use command line curl </li></ul>
  133. 133. Working with Web Services
  134. 134. Working with Web Services <ul><li>Consuming existing services
  135. 135. Web services overview
  136. 136. Data types
  137. 137. Service types
  138. 138. Debugging
  139. 139. Using services from PHP </li></ul>
  140. 140. Top tips <ul><li>If your app can't talk to the service, can you get closer to the service?
  141. 141. If you control both server and client, add debug output
  142. 142. Use proxies to record what happens
  143. 143. Start with the lowest common denominator and work up </li></ul>

×