Three Ways to Make a POST Request from PHP

EDIT: A more modern take on this topic is here http://www.lornajane.net/posts/2018/make-a-post-request-from-php-with-guzzle

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.

In Conclusion

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.

29 thoughts on “Three Ways to Make a POST Request from PHP

  1. Good article! I prefer curl personally. You made a typo in the curl code example. In the third line with curl_setopt you use the variable $curl which should be $ch like the others :)

  2. Actually, there is a clean third way using built-in methods:

    $params = array(‘http’=>array(‘method’=>’post’,’content’=>http_build_query($postArr)));
    $context= stream_context_create($params);
    $stream= fopen($url, ‘rb’, false, $context);

    • Here’s another variant on the same approach, setting a header for XML data and using file_get_contents() instead of fopen() (but the same fopen wrappers are used).

      [geshi lang=php]
      $context = stream_context_create(array(
      ‘http’ => array(
      ‘method’ => ‘POST’,
      ‘header’ => ‘Content-Type: application/xml’,
      ‘content’ => $xml
      )
      ));

      $result = file_get_contents($url, false, $context);
      [/geshi]

    • I had trouble at first with your example code on PHP 7 — I was receiving an empty $_POST array. Sending lower case ‘post’ was recognized using the file_get_contents(‘php://input’) method, but was *not* recognized via the $_POST function. Sending upper case ‘POST’ was recognized by both methods.

  3. Right, PHP supports http natively as well, and is very easy to implement.

    cURL and pecl’s http however help to process complex requests. Additionnaly cURL supports all kind of protocols, including sftp/ssh2/ftps :)

  4. Goodness, what a lot of comments! Thanks everyone for taking the time to comment, what excellent and useful contributions!! I definitely learned a few tricks from my readers today :)

  5. One other advantage of cURL and pecl_http (which is built on libcurl, the same library as the cURL extension uses) is that they support parallel requests, which can be a significant performance boost if you need to execute multiple requests from a single process. Look at the curl_multi_* functions in cURL and HttpRequestPool in pecl_http.

  6. yeh, as noticed by first comment you forget to see in PEAR. It is pretty simple to use php based library because it will be supported even curl or pecl libraries are unavailable.

  7. you still have a typo in your example:
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    should be
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    ..at least i assume it should :-)

  8. Pingback: Bit.ly API: Bundles and Short URLs | LornaJane

  9. Pingback: PHP Generating Post Data - PHP Solutions - Developers Q & A

    • Probably you don’t want to POST it if everything you need is already in the URL. Try:

      file_get_contents(“http://www.site.com/ap.aspx?foo=bar”…”);

  10. I have a requirement, calling nearly 50+ URLs to fetch the data. I tried in many ways. Finally Stick with HTTPRequestPool. Because it was faster than any other methods. I tried below methods.

    1.file_get_contents($url) – took about 2 mins to complete all 50 requests
    2.curl – took about 45 to 50 seconds to complete all 50 requests
    3.HTTPRequest – took about 20 to 30 seconds to complete all 50 requests
    4.HttpRequestPool – took about 10 to 15 seconds to complete all 50 requests

    But still 10 to 15 seconds is also slow, when compare to my competitors. I want to complete all the 50 requests in a max of 3 to 6 seconds. How can I achieve my target time frame. Is there any alternatives apart from the above in PHP. If yes can anybody please tell me those.

    Please help me to resolve this issue.
    Thanks,
    Sudhakar

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.