My job at WooThemes enables me to work on all sorts of cool projects and enables me to push the limits of what is possible with WordPress each day. Some of the projects I work on that I enjoy the most is projects that involves interfacing with any sort of API service, I am a sucker for an API 🙂

In a recent project which involved interfacing with an API service I had to upload a file to the service, and wanting to stay true to the WordPress way I naturally built the whole API interface layer using native WordPress functionality. This involved making use of the wp_remote_request function, which is called by the wrapper function wp_remote_post to send through POST requests.

After Googling for quite a while I just could not get any examples of uploading files in binary using wp_remote_post or wp_remote_request, for that matter, which resulted in me having to figure this out on my own.

The API document was straight forward, in order to upload a file you need to post it as binary to API endpoint, now there are plenty of example of doing this using cURL, so I used that as a starting point and converted it to WordPress native functionality.

The cURL way of uploading the file


curl -u username:password -H "Content-Type: application/binary" \
–data-binary @file.dat -X POST \
"https://domain.com/api/v2/uploads.json?filename=myfile.dat"

view raw

curl.sh

hosted with ❤ by GitHub

Digging through some cURL docs I found that I basically needed to set a header to binary, and then stream the file binary content as the body, and found the following way of uploading the file using either wp_remote_request or wp_remote_post


<?php
// wp_remote_request way
$file = @fopen( 'path/to/file.txt', 'r' );
$file_size = filesize( 'path/to/file.txt' );
$file_data = fread( $file, $file_size );
$args = array(
'method' => 'POST'
'headers' => array(
'accept' => 'application/json', // The API returns JSON
'content-type' => 'application/binary', // Set content type to binary
),
'body' => $file_data
);
$result = wp_remote_request( 'https://domain.com/api/v2/uploads.json?filename=myfile.dat&#39; $args );
// wp_remote_post way
$file = @fopen( 'path/to/file.txt', 'r' );
$file_size = filesize( 'path/to/file.txt' );
$file_data = fread( $file, $file_size );
$args = array(
'headers' => array(
'accept' => 'application/json', // The API returns JSON
'content-type' => 'application/binary', // Set content type to binary
),
'body' => $file_data
);
$result = wp_remote_post( 'https://domain.com/api/v2/uploads.json?filename=myfile.dat&#39; $args );
?>

view raw

file.php

hosted with ❤ by GitHub

The above code shows examples of using either wp_remote_request or wp_remote_post, as you can see there is not much difference between the two, instead that with wp_remote_post there is no need to set the method header as it is a wrapper function that does that automatically.

In some cases API services will require you to do uploads with PUT requests instead of POST, in that case you will use the wp_remote_request function and just set the method header to PUT instead of POST to make a PUT request.

Hope this helps someone out there that has also struggled to do this using native WordPress functions.