Skip to content

Instantly share code, notes, and snippets.

@ssigwart
Created January 24, 2015 16:21
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ssigwart/83c394fb689d4797ffc3 to your computer and use it in GitHub Desktop.
Save ssigwart/83c394fb689d4797ffc3 to your computer and use it in GitHub Desktop.
Build multipart/form-data in PHP
/**
* Build multipart/form-data
*
* @param array @$data Data
* @param array @$files 1-D array of files where key is field name and value if file contents
* @param string &$contentType Retun variable for content type
*
* @return string Encoded data
*/
function buildMultipartFormData(array &$data, array &$files, &$contentType)
{
$eol = "\r\n";
// Build test string
$testStr = '';
array_walk_recursive($data, function($item, $key) use (&$testStr, &$eol) {
$testStr .= $key . $eol . $item . $eol;
});
// Get file content type and content. Add to test string
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$fileContent = array();
$fileContentTypes = array();
foreach ($files as $key=>$filename)
{
$fileContent[$key] = file_get_contents($filename);
$fileContentTypes[$key] = finfo_file($finfo, $filename);
$testStr .= $key . $eol . $fileContentTypes[$key] . $eol. $fileContent[$key] . $eol;
}
finfo_close($finfo);
// Find a boundary not present in the test string
$boundaryLen = 6;
$alpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
do {
$boundary = '--';
for ($i = 0; $i < $boundaryLen; $i++)
{
$c = rand(0, 61);
$boundary .= $alpha[$c];
}
// Check test string
if (strpos($testStr, $boundary) !== false)
{
$boundary = null;
$boundaryLen++;
}
} while ($boundary === null);
unset($testStr);
// Set content type
$contentType = 'multipart/form-data, boundary='.$boundary;
// Build data
$rtn = '';
$func = function($data, $baseKey = null) use (&$func, &$boundary, &$eol)
{
$rtn = '';
foreach ($data as $key=>&$value)
{
// Get key
$key = $baseKey === null ? $key : ($baseKey . '[' . $key . ']');
// Add data
if (is_array($value))
$rtn .= $func($value, $key);
else
$rtn .= '--' . $boundary . $eol . 'Content-Disposition: form-data; name="'.$key.'"' . $eol . $eol . $value . $eol;
}
return $rtn;
};
$rtn = $func($data);
// Add files
foreach ($files as $key=>$filename)
{
$rtn .= '--' . $boundary . $eol . 'Content-Disposition: file; name="'.$key.'"; filename="'.basename($filename).'"' . $eol
. 'Content-Type: ' . $fileContentTypes[$key] . $eol
. 'Content-Transfer-Encoding: binary' . $eol . $eol
. $fileContent[$key] . $eol;
}
return $rtn . '--' . $boundary . '--' . $eol;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment