tags:

views:

56

answers:

2

Hi,

I am in a situation where I cannot use PHP cURL module to POST my form data. I have found a great blog post showing how to POST without using cURL here: HTTP POST from PHP, without cURL

Here's my problem though. When I attempt to send my POST request, the request hits the (other) server but the content (POST data) is not transmitted. The other server does not get the content. HOWEVER, if I do use cURL, it works fine. What am I missing? How can I recreate the cURL HTTP POST request without using cURL?

Here is the cURL code that works ($this->params is just $_POST which contains the form data):

$ch = curl_init($this->url);

$params = http_build_query($this->params);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params );
curl_setopt($ch, CURLOPT_FOLLOWLOCATION  ,1);
curl_setopt($ch, CURLOPT_HEADER      ,0);  // DO NOT RETURN HTTP HEADERS
curl_setopt($ch, CURLOPT_RETURNTRANSFER  ,1);  // RETURN THE CONTENTS OF THE CALL

$result = curl_exec($ch);
curl_close($ch);

return $result;

And here is my non-cURL version that does not work:

$postStr = http_build_query($this->params);

$opts = array(
    'http'=>array(
        'method' => $method,
        //'header' => 'Content-type: application/x-www-form-urlencoded',
        //'header' => 'content-type: multipart/form-data',
        'content-type' => 'application/x-www-form-urlencoded',
        'content-encoding' => 'UTF-8',
        'content' => $postStr
    )
);

$context = stream_context_create($opts);

$result = file_get_contents($this->url, false, $context);

return $result;

There are no errors or warnings. Just, the accepting server doesn't appear to the contents. Any ideas?

A: 

It is likely your $method is not populated with 'POST'. The other major reason would have been an open_basedir restriction, but that would have generated a warning.

Try explicitly naming "POST"

$opts = array(
    'http'=>array(
        'method' => 'POST',
        'content-type' => 'application/x-www-form-urlencoded',
        'content-encoding' => 'UTF-8',
        'content' => $postStr
    )
);
sleepynate
Ah! Ok, so it was a simple case-sensitivity mistake. The $method was set to 'post' instead of 'POST'. Oh geesh... Thank you for taking the time to help! It's working fine now.
Kevin
+1  A: 

Your non-CURL version is incomplete.

you must use fopen after creating the context with stream_context_create.

Solution: Use this function: Do it like this:

<?php
function do_post_request($url, $data, $optional_headers = null)
{
  $params = array('http' => array(
              'method' => 'POST',
              'content' => $data
            ));

  if ($optional_headers !== null)
      $params['http']['header'] = $optional_headers;

  $ctx = stream_context_create($params);
  $fp = @fopen($url, 'rb', false, $ctx);

  if (!$fp)
      throw new Exception("Problem with $url, $php_errormsg");

  $response = @stream_get_contents($fp);

  if ($response === false)
      throw new Exception("Problem reading data from $url, $php_errormsg");

  return $response;
}
shamittomar
The function: file_get_contents() replaces the need for fopen. You can see a different example (than the one in the blog) here:http://www.php.net/manual/en/context.http.php
Kevin