This post comes as a result of my having browsed http://www.lornajane.net/posts/2010/Three-Ways-to-Make-a-POST-Request-from-PHP. The tutorial is very easy to follow as it clearly describes the syntax for submitting data via the POST method, using two different PHP extensions, ext/curl and pecl_http. I eagerly awaited the moment that I would take the different code snippets out for a test-drive.
The first bit I decided to try out was the curl snippet. I’ve used PHP’s curl extension before. In fact, I wrote an entire article about it for php|architect (see the February 2010 issue). What caught my attention was that the code involved having PHP/CURL post to an XMLRPC service at Flickr. I was intrigued to see how this would work.
Unfortunately, I was unable to make the code perform as I had hoped. There is a minor typo such that the line that contains a variable $curl should instead have $ch. But, that is hardly a stumbling block and easy to fix. The fact that the $xml variable is used without being set to any meaningful value for the xmlrpc service at flickr is an issue, but even that in the big picture is just a small hurdle.
However, after some investigation, I realized that flickr had probably made some changes in their web services. I needed to revise the code so that instead of using flickr’s xmlrpc service to execute the test.echo function, I would use the rest service. But, I can still use curl to post data to it, as you will see shortly.
$url = 'http://api.flickr.com/services/rest/'; $data = array("method" => "flickr.test.echo", "foo" => "bar", "format" => "rest", "api_key" => "your api number goes here"); $qs = http_build_query($data);
In order to have the data posted to the above-indicated url, I create the query string with the necessary key/value pairs that flickr’s test.echo function needs and include the optional pair foo/bar. Note that the data is urlencoded, too.
Then, I go ahead and create a curl session, passing in the url as a parameter. I declare the $response before using it to avoid parser error messages.
$ch = curl_init($url); $response = '';
Next, I set some options, making sure that curl knows to send the data via POST. Instead of appending the query string to the url, I indicate to curl that the data is in the content body by providing $qs as a parameter to setting the curl option CURLOPT_POSTFIELDS, as follows:
curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $qs); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch);
To view the results, I finally make use of simplexml and use it to create such an object of the returned xml string value. Using the simplexml element’s asXML() method together with var_dump, I can quickly view the results.
$s = simplexml_load_string ($response); var_dump($s->asXML());
The $url, $qs and $response variables above also work with the next example using pecl_http, as follows:
$response = http_post_data($url, $qs); $body = explode("<?",$response); echo '<?' . $body;
There is a more elegant way to get the content body from the response, if you use pecl_http’s classes. This is probably why I like best the last example using the class interface of the http extension along with the above indicated values for $url and $qs, as follows:
echo '<h1 style="color:violet">Response</h1>'; $request = new HTTPRequest($url, HTTP_METH_POST); $request->setQueryData($qs); $request->send(); echo $request->getResponseBody();
Notice how in this last example, I have the request object invoke its setQueryData() method with respect to the query string. After that, the only thing left to do is send the request and get the response. Notice, how I don’t even need the variable $response. I simply display the results by using echo along with the request object’s getResponseBody() method.
I offer the snippets above with the caveat that flickr can change its API at any time. I should also like to suggest that you read Lorna Jane’s post, including the comments, especially since there are excellent suggestions about how to use PHP’s builtins for POSTing data.