There's a slide deck, some exercises and a sample repo on GitHub ... let's dive in! Continue reading
HEADrequest changes the output I get, so I really do want to
GETand then only see the headers.
Handily, when you use the
-v verbose flag with curl, it sends the output to stdout as usual, but the extra information including the headers goes to stderr. This means that I can therefore view the headers only throwing away stdout completely:
curl -v -s http://awesome-site.com 1> /dev/null
(you need the
-s to stop curl from "helpfully" printing progress bars as well)
I put the data into a separate file,
data.txt and then used curl to direct that data at my local URL:
curl -X POST http://localhost/app/test.php --data @data.txt
I find this approach useful for testing, but since I had to look up how to do it, I thought I'd put it here for reference!
Here's a simple example, using PHP's curl extension, of using the bit.ly API to get a short URL, using PHP (you need an API key, but if you're a registered bit.ly user, you can log in and then find yours at http://bitly.com/a/your_api_key).
$ch = curl_init('http://api.bitly.com/v3/shorten?login=username&apiKey=R_secret&longUrl=http%3A%2F%2Flornajane.net'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); print_r(json_decode($result));
-c to Save a Cookie
Pass the -c switch followed by a filename and curl will write the cookies to a file. This is the "cookie jar" and you can dip into it whenever you want to send the cookies back with a future request. For example:
curl -c cookies.txt http://www.lornajane.net
This writes a file named cookies.txt to the local directory. When I look in it, it contains:
# Netscape HTTP Cookie File
# This file was generated by libcurl! Edit at your own risk.
www.lornajane.net FALSE / FALSE 0 s9y_4e071c5ccc553288993faf0369cb076c 539e01676501366ea0f04e2646b1a31d
-b to Send Cookies
Function HttpRequest::addRawPostData() is deprecated
It isn't obvious from the PHP manual page what I ought to do instead, however further inspection shows that it is recommended to use setBody() instead. This can be used in exactly the same way, and my code seems to work perfectly well with this substitution. If you have any more information about this change, leave me a comment - I'd be interested to hear it.
I've been doing a lot of work with services and working with them in various ways from PHP. There are a few different ways to do this, PHP has a curl extension which is useful, and if you can add PECL extensions then pecl_http is a better bet but there are a couple of different ways of using it. This post shows all these side-by-side.
POSTing from PHP Curl
This is pretty straightforward once you get your head around the way the PHP curl extension works, combining various flags with setopt() calls. In this example I've got a variable $xml which holds the XML I have prepared to send - I'm going to post the contents of that to flickr's test method.
$url = 'http://api.flickr.com/services/xmlrpc/'; $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch);
First we initialised the connection, then we set some options using setopt(). These tell PHP that we are making a post request, and that we are sending some data with it, supplying the data. The CURLOPT_RETURNTRANSFER flag tells curl to give us the output as the return value of curl_exec rather than outputting it. Then we make the call and close the connection - the result is in $response.
POSTing from Pecl_Http
Pecl_Http has two interfaces - one procedural and one object-oriented; we'll start by looking at the former. This is even simpler than in curl, here's the same script translated for pecl_http:
$url = 'http://api.flickr.com/services/xmlrpc/'; $response = http_post_data($url, $xml);
This extension has a method to expressly post a request, and it can optionally accept data to go with it, very simple and easy.
POSTing from Pecl_Http: the OO interface
Finally let's see what the OO verison of the extension looks like. Exactly the same call as both the above examples, but using the alternative interface, means our code looks like this:
$url = 'http://api.flickr.com/services/xmlrpc/'; $request = new HTTPRequest($url, HTTP_METH_POST); $request->setRawPostData($xml); $request->send(); $response = $request->getResponseBody();
This example is quite a bit longer than the previous one, and you might think this indicates that this approach is more complicated. In some senses that is true and its probably overkill for our extremely trivial example. However it is worth mentioning that the pecl_http extension is extremely flexible and powerful, and can handle some cases that the curl extension can't. So even if it looks more complicated here, it can still be an excellent choice to implement.
That was a very fast round-up of three ways you could make an arbitrary web service call from PHP - hopefully these examples are clear and will help anyone just starting to implement something along these lines.