Skip to content

Instantly share code, notes, and snippets.

@mssyogi
Forked from iansltx/MultiPartFromStrings.php
Created November 27, 2017 11:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mssyogi/4bc5f22c8342cae1f26cd28c32bfb2d6 to your computer and use it in GitHub Desktop.
Save mssyogi/4bc5f22c8342cae1f26cd28c32bfb2d6 to your computer and use it in GitHub Desktop.
Multipart file uploads in PHP from strings
<?php
/**
* PHP's curl extension won't let you pass in strings as multipart file upload bodies; you
* have to direct it at an existing file (either with deprecated @ syntax or the CURLFile
* type). You can use php://temp to get around this for one file, but if you want to upload
* multiple files then you've got a bit more work.
*
* This function manually constructs the multipart request body from strings and injects it
* into the supplied curl handle, with no need to touch the file system.
*
* @param $ch resource curl handle
* @param $boundary string a unique string to use for the each multipart boundary
* @param $fields string[] fields to be sent as fields rather than files, as key-value pairs
* @param $files string[] fields to be sent as files, as key-value pairs
* @return resource the curl handle with request body, and content type set
* @see http://stackoverflow.com/a/3086055/2476827 was what I used as the basis for this
**/
function buildMultiPartRequest($ch, $boundary, $fields, $files) {
$delimiter = '-------------' . $boundary;
$data = '';
foreach ($fields as $name => $content) {
$data .= "--" . $delimiter . "\r\n"
. 'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n"
. $content . "\r\n";
}
foreach ($files as $name => $content) {
$data .= "--" . $delimiter . "\r\n"
. 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '"' . "\r\n\r\n"
. $content . "\r\n";
}
$data .= "--" . $delimiter . "--\r\n";
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: multipart/form-data; boundary=' . $delimiter,
'Content-Length: ' . strlen($data)
],
CURLOPT_POSTFIELDS => $data
]);
return $ch;
}
// and here's how you'd use it
$ch = curl_init('http://httpbin.org/post');
$ch = buildMultiPartRequest($ch, uniqid(),
['key' => 'value', 'key2' => 'value2'], ['somefile' => 'contents!', 'someotherfile' => 'yoloswag']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment