26

I'm able to run the following curl command (at the command line) successfully:

curl -XPOST --basic -u user:password -H accept:application/json -H Content-type:application/json --data-binary '{ "@queryid" : 1234 }' http://localhost/rest/run?10

Here is what I'm doing so far however it doesn't seem to be working with the REST service I'm using:

$headers = array(
    'Accept: application/json',
    'Content-Type: application/json',
);

$url = 'http://localhost/rest/run?10';
$query = '{ "@queryid" : 1234 }';

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "user:password");

curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
curl_setopt($ch, CURLOPT_POSTFIELDSIZE, strlen($query));

$output = curl_exec($ch);

echo $output;

What is the correct way when trying to convert --data-binary using a PUT method?

George G
  • 7,443
  • 12
  • 45
  • 59

3 Answers3

44

Instead of creating a temp file on disk you can use php://temp.

$body = 'the RAW data string I want to send';

/** use a max of 256KB of RAM before going to disk */
$fp = fopen('php://temp/maxmemory:256000', 'w');

if (!$fp) 
{
    die('could not open temp memory data');
}

fwrite($fp, $body);
fseek($fp, 0); 

curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_INFILE, $fp); // file pointer
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));                            

The upside is no disk IO so it should be faster and less load on your server.

George G
  • 7,443
  • 12
  • 45
  • 59
Benson Wong
  • 631
  • 6
  • 5
  • 1
    This is brilliant! i had no idea about temp FDs, it helped me loads resuming an upload with curl for youtube (read remaining bytes into mem and then upload as normal using your method) – Question Mark Jun 11 '12 at 16:41
  • Shouldn't the mode be 'w+' ? – flm Sep 04 '13 at 20:27
35

Hi all I got it working using this configuration:

// Start curl
$ch = curl_init();
// URL for curl
$url = "http://localhost/";

// Clean up string
$putString = stripslashes($query);
// Put string into a temporary file
$putData = tmpfile();
// Write the string to the temporary file
fwrite($putData, $putString);
// Move back to the beginning of the file
fseek($putData, 0);

// Headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Binary transfer i.e. --data-BINARY
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
// Using a PUT method i.e. -XPUT
curl_setopt($ch, CURLOPT_PUT, true);
// Instead of POST fields use these settings
curl_setopt($ch, CURLOPT_INFILE, $putData);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($putString));

$output = curl_exec($ch);
echo $output;

// Close the file
fclose($putData);
// Stop curl
curl_close($ch);

:)

  • 2
    +1 Thanks for taking the time to come back and answer your own Q. You saved me a lot of time – Basic Aug 10 '12 at 13:29
7

All all that needs to be set is the custom request to reuse post method.

CURLOPT_URL=>$url,
CURLOPT_CUSTOMREQUEST=>'PUT',
CURLOPT_POSTFIELDS=>$params,
  • this pointer was helpful to me when accessing a REST API where no actual data was being transferred in the request (the url contains the parameters) – Loopo Jan 06 '15 at 11:33
  • This method makes talking to rest via PUT a whole lot easier. No file tingeling, just use the POST infrastructure. – kratenko Feb 25 '15 at 17:00