17

I'm using an API that wants me to send a POST with the binary data from a file as the body of the request. How can I accomplish this using PHP cURL?

The command line equivalent of what I'm trying to achieve is:

curl --request POST --data-binary "@myimage.jpg" https://myapiurl
Nocklas
  • 1,367
  • 4
  • 15
  • 27
  • What have you tried? Here is an example using cURL: http://stackoverflow.com/questions/9134003/binary-data-posting-with-curl Just need to PHPize it up a bit. – ficuscr Aug 12 '15 at 17:08

6 Answers6

39

You can just set your body in CURLOPT_POSTFIELDS.

Example:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,            "http://url/url/url" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POST,           1 );
curl_setopt($ch, CURLOPT_POSTFIELDS,     "body goes here" ); 
curl_setopt($ch, CURLOPT_HTTPHEADER,     array('Content-Type: text/plain')); 

$result=curl_exec ($ch);

Taken from here

Of course, set your own header type, and just do file_get_contents('/path/to/file') for body.

Community
  • 1
  • 1
vfsoraki
  • 2,186
  • 1
  • 20
  • 45
4

to set body to binary data and upload without multipart/form-data, the key is to cheat curl, first we tell him to PUT, then to POST:

    <?php
    
    $file_local_full = '/tmp/foobar.png';
    $content_type = mime_content_type($file_local_full);

    $headers = array(
        "Content-Type: $content_type", // or whatever you want
    );

    $filesize = filesize($file_local_full);
    $stream = fopen($file_local_full, 'r');

    $curl_opts = array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_PUT => true,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_INFILE => $stream,
        CURLOPT_INFILESIZE => $filesize,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1
    );

    $curl = curl_init();
    curl_setopt_array($curl, $curl_opts);

    $response = curl_exec($curl);

    fclose($stream);

    if (curl_errno($curl)) {
        $error_msg = curl_error($curl);
        throw new \Exception($error_msg);
    }

    curl_close($curl);

credits: How to POST a large amount of data within PHP curl without memory overhead?

2

This can be done through CURLFile instance:

$uploadFilePath = __DIR__ . '/resource/file.txt';

if (!file_exists($uploadFilePath)) {
    throw new Exception('File not found: ' . $uploadFilePath);
}

$uploadFileMimeType = mime_content_type($uploadFilePath);
$uploadFilePostKey = 'file';

$uploadFile = new CURLFile(
    $uploadFilePath,
    $uploadFileMimeType,
    $uploadFilePostKey
);

$curlHandler = curl_init();

curl_setopt_array($curlHandler, [
    CURLOPT_URL => 'https://postman-echo.com/post',
    CURLOPT_RETURNTRANSFER => true,

    /**
     * Specify POST method
     */
    CURLOPT_POST => true,

    /**
     * Specify array of form fields
     */
    CURLOPT_POSTFIELDS => [
        $uploadFilePostKey => $uploadFile,
    ],
]);

$response = curl_exec($curlHandler);

curl_close($curlHandler);

echo($response);

See - https://github.com/andriichuk/php-curl-cookbook#upload-file

0

Try this:

$postfields = array(
    'upload_file' => '@'.$tmpFile
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url.'/instances');
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);//require php 5.6^
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$postResult = curl_exec($ch);

if (curl_errno($ch)) {
    print curl_error($ch);
}
curl_close($ch); 
Pang
  • 9,564
  • 146
  • 81
  • 122
0

Below solution worked fine for me.

$ch = curl_init();

$post_url = "https://api_url/"
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');

$post = array(
            'file' => '@' .realpath('PATH_TO_DOWNLOADED_ZIP_FILE')
         );
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

$headers = array();
$headers[] = 'Authorization: Bearer YOUR_ACCESS_TOKEN';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

refered: curl to php-curl

Siva
  • 375
  • 3
  • 5
-2

You need to provide appropriate header to send a POST with the binary data.

$header = array('Content-Type: multipart/form-data');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($resource, CURLOPT_POSTFIELDS, $arr_containing_file);

Your $arr_containing_file can for example contain file as expected (I mean, you need to provide appropriate expected field by the API service).

$arr_containing_file = array('datafile' => '@inputfile.ext');
Samar
  • 1,865
  • 12
  • 13