PHP - 用二进制数据打包数组
PHP - Pack array with binary data
有一个服务 (php) 将图像发送到客户端 (php)。
header('Content-Type: image/png');
readfile($image);
如果不仅需要发送图像还需要发送一些数据怎么办。
$arrayToSend = [
'image' => file_get_contents($image),
'some_data' => [
'a' => 1,
'b' => 2
]
];
服务如何打包 $arrayToSend 以便客户端可以解包?
没有将图像转换为 base64(因为尺寸太大)。
也许您可以将 some_data-a
和 some_data-b
作为 headers 传递?例如,作为 cookie。
您可以通过此文档帮助自己:https://developer.mozilla.org/pl/docs/Web/HTTP/Headers 了解有关 headers 的更多信息。
@Danon 的 header 方法可能是您通过 HTTP 进行通信的方式,但其他传输可能不支持发送额外的 headers,因此您需要将它们打包与二进制数据,然后在接收端解压。
<?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!';
}
有一个服务 (php) 将图像发送到客户端 (php)。
header('Content-Type: image/png');
readfile($image);
如果不仅需要发送图像还需要发送一些数据怎么办。
$arrayToSend = [
'image' => file_get_contents($image),
'some_data' => [
'a' => 1,
'b' => 2
]
];
服务如何打包 $arrayToSend 以便客户端可以解包?
没有将图像转换为 base64(因为尺寸太大)。
也许您可以将 some_data-a
和 some_data-b
作为 headers 传递?例如,作为 cookie。
您可以通过此文档帮助自己:https://developer.mozilla.org/pl/docs/Web/HTTP/Headers 了解有关 headers 的更多信息。
@Danon 的 header 方法可能是您通过 HTTP 进行通信的方式,但其他传输可能不支持发送额外的 headers,因此您需要将它们打包与二进制数据,然后在接收端解压。
<?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!';
}