@Danon's header approach is probably the way to go if you're communicating over HTTP, but other transports may not support sending additional headers, so you would need to pack them in with the binary data, then unpack on the receiving side.
<?php
class Codec
{
/**
* Pack metadata along with binary data
*
* @param $meta
* @param $data
* @return false|string
*/
public static function encode($meta, $data)
{
$meta = base64_encode($meta);
//determine length of metadata
$metaLength = strlen($meta);
//The first part of the message is the metadata length
$output = pack('VA*', $metaLength, $meta);
//Length and metadata are set, now include the binary data
$output .= $data;
return $output;
}
/**
* Unpack data encoded via the encode function.
* Returns an array with "meta" and "data" elaments
*
* @param $content
* @return array
*/
public static function decode($content)
{
//Get the length of the metadata content
$metaLength = unpack('V', $content)[1];
//Slice out the metatdata, offset 4 to account for the length bytes
$metaPacked = substr($content, 4, $metaLength);
//Unpack and base64 decode the metadata
$meta = unpack('A*', $metaPacked)[1];
$meta = base64_decode($meta);
//The binary data is everything after the metadata
$data = substr($content, $metaLength+4);
return [
'meta' => $meta,
'data' => $data
];
}
}
//Load contents of a binary file
$imageFilePath = 'path_to_image.png';
$data = file_get_contents($imageFilePath);
//Arbitrary metadata - could be anything, let's use JSON
$meta = [
'filename' => 'foo.png',
'uid' => 12345,
'md5' => md5_file($imageFilePath)
];
$metaJson = json_encode($meta);
//Encode the message, you can then send this to the receiver
$payload = Codec::encode($metaJson, $data);
//Receiver decodes the message
$result = Codec::decode($payload);
//Decode our JSON string
$resultMeta = json_decode($result['meta'], true);
echo 'Filename: '.$resultMeta['filename'].PHP_EOL;
echo 'UID: '.$resultMeta['uid'].PHP_EOL;
//We included an MD5 hash of the file, so we can verify here
if($resultMeta['md5'] != md5($result['data']))
{
echo 'MD5 mismatch!';
}