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

7,260

Published on

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

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

No Downloads
Views
Total Views
7,260
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
557
Comments
0
Likes
12
Embeds 0
No embeds

No notes for slide
  • can independently scale those modular elements
  • 15 mins
  • parse_str(file_get_contents(&amp;quot;php://input&amp;quot;),$post_vars);
  • 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>
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×