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?

0

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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)
Shouldn't the mode be 'w+' ?
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);

:)

1 Comment

+1 Thanks for taking the time to come back and answer your own Q. You saved me a lot of time
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,

2 Comments

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)
This method makes talking to rest via PUT a whole lot easier. No file tingeling, just use the POST infrastructure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.